基于比较的内排序算法(一)

今天把基于比较的内排序算法写了一遍,其中包括bubbleSort, selectSort, insertSort, heapSort, quickSort, shellShort。 mergeSort留了接口以后补上,下篇再把几种排序的时间复杂度、稳定性、适用情况总结一下。

 

#include <iostream> #include <string> #include <cstring> #include <cmath> #include <cassert> #include <ctime> #include <cstdlib> using namespace std; class sort{ public: sort(int*,int); ~sort(); void setBeginEnd(int, int); void setData(int*, int); void move(int); static const string& getName(int); static int getWays(); void dump() const; private: void bubbleSort(); void selectSort(); void insertSort(); void mergeSort(); void quickSort(); void heapSort(); void shellSort(); void swap(int&,int&); void quickSort1(int, int); int partition(int,int); void heapify(int); void creatHeap(); private: int *vData; int vSize; int begin, end; typedef void (sort::*FUNC)(); static const FUNC funcPtr[]; static const string name[]; }; const string sort::name[]={"bubbleSort", "selectSort", "insertSort", "mergeSort", "quickSort", "heapSort", "shellSort"}; const sort::FUNC sort::funcPtr[]={&sort::bubbleSort, &sort::selectSort, &sort::insertSort, &sort::mergeSort, &sort::quickSort, &sort::heapSort, &sort::shellSort}; sort::sort(int* A, int n):vSize(n),begin(0),end(n-1){ vData = new int[n]; memmove(vData, A, n*sizeof(int)); } sort::~sort(){ delete [] vData; } void sort::setBeginEnd(int s, int t){ if(s > t){ begin = t; end = s; }else{ begin = s; end = t; } } void sort::setData(int* A, int n){ delete [] vData; vData = new int[n]; memmove(vData, A, n*sizeof(int)); vSize = n; begin = 0; end = n-1; } void sort::move(int t){ (this->*funcPtr[t])(); } const string& sort::getName(int i){ return name[i]; } int sort::getWays(){ return sizeof(funcPtr)/sizeof(FUNC); } void sort::dump() const{ assert(begin<=end); if(begin==end){ cout << "(" << vData[begin] << ")" << endl; }else{ cout << "(" << vData[begin]; for(int i=begin+1;i<=end;i++) cout << ", " << vData[i]; cout << ")" << endl; } } void sort::bubbleSort(){ for(int i=0;i<end-begin;i++) for(int j=begin+1;j<=end-i;j++) if(vData[j-1] > vData[j]) swap(vData[j-1],vData[j]); } void sort::selectSort(){ for(int i=0;i<end-begin;i++){ int min = begin+i; for(int j=begin+i+1;j<=end;j++){ if(vData[j] < vData[min]) min = j; } swap(vData[min], vData[begin+i]); } } void sort::insertSort(){ for(int i=begin+1,j;i<=end;i++){ int tmp=vData[i]; for(j=i-1;j>=begin && tmp<vData[j];j--){ vData[j+1]=vData[j]; } vData[j+1]=tmp; } } void sort::mergeSort(){ } void sort::quickSort(){ quickSort1(begin, end); } void sort::heapSort(){ creatHeap(); int tmp=vSize; for(int i=vSize-1;i>=0;i--){ swap(vData[i],vData[0]); vSize--; heapify(0); } vSize=tmp; } void sort::shellSort(){ int step = sqrt(vSize); for(int i=step;i>=1;i--){ for(int j=begin+i,k;j<=end;j+=i){ int tmp=vData[j]; for(k=j-i;k>=begin && tmp<vData[k];k-=i) vData[k+i]=vData[k]; vData[k+i]=tmp; } } } void sort::swap(int& a, int& b){ int tmp = a; a = b; b = tmp; } void sort::quickSort1(int s, int f){ if(s < f){ int pos = partition(s,f); quickSort1(s,pos-1); quickSort1(pos+1,f); } } int sort::partition(int s, int f){ int l=s, r=f; int base = vData[l]; while(l<r){ while(vData[l] <= base && l<=r) l++; while(vData[r] >= base && l<=r) r--; if(l<r) swap(vData[l], vData[r]); } swap(vData[r], vData[s]); return r; } /*node from 0 to n-1, node i's left child is 2*i+1 and right child * is 2*i+2, and parent is (i-1)/2, leaf node is from size/2 to size*/ void sort::heapify(int j){ #define lc(i) (2*i+1) #define rc(i) (2*i+2) #define pa(i) ((i-1)/2) if(j<vSize/2){ int max = vData[j]; bool isLeft, isRight; isLeft = isRight = false; if(vData[rc(j)] > max && rc(j) < vSize){ max = vData[rc(j)]; isRight = true; } if(vData[lc(j)] > max && lc(j) < vSize){ isLeft = true; } if(isLeft){ swap(vData[j],vData[lc(j)]); heapify(lc(j)); }else if(isRight){ swap(vData[j],vData[rc(j)]); heapify(rc(j)); } } } void sort::creatHeap(){ for(int i=vSize/2-1;i>=0;i--) heapify(i); } void print(int *A, int n){ if(n!=0){ cout << "(" << A[0]; for(int i=1;i<n;i++) cout << ", " << A[i]; cout << ")" << endl; }else cout << "empty!" << endl; } int main(int argc, char *argv[]) { int A[] ={10,11,18,12,13,16,14,15,19,17,8,7,3,2,4,6,1,9,0,5}; int *B, num; clock_t start, finish; if(argc==1){ num = sizeof(A)/sizeof(int); B = new int[num]; memmove(B,A,sizeof(A)); }else if(argc>=2){ srand(time(NULL)); num = atoi(argv[1]); const int MAX = 1000; B = new int[num]; for(int i=0;i<num;i++) B[i] = rand() % MAX; } for(int i=0;i<sort::getWays();i++){ sort s(B,num); start = clock(); s.move(i); finish = clock(); cout << sort::getName(i) << "/t"; cout << (double)(finish-start)/CLOCKS_PER_SEC<<"s"<<endl; #ifdef DEBUG print(B,num); s.dump(); #endif } return 0; }

你可能感兴趣的:(基于比较的内排序算法(一))