最经在看大话数据结构。本文中的优化内容基本是该书上的总结。代码可能有点不同。
快速排序是21世纪经典的十大算法之一。其思路为:选取一个中枢元素,然后通过一种方法,在该序列中唯一确定了该中枢位置,即是前面的都小于该中枢值,后面的都比该中枢值大。从而将待排序列,分割成了两半。当然这是最好的情况下,此时效果最好。下面从3方面来优化。
未经过优化的排序为:
void quicksort(int a[],int first,int last) { if(first<last) { int i=first,j=last; int tmp=a[first]; while( i<j ) { while(i<j && a[j]>=tmp) --j; // find the first index j that a[j] < tmp from right to left if(i<j) a[i++]=a[j]; // cover the a[i]. while( i<j && a[i]<tmp) i++; //find the first index i that a[i]>tmp from left to right if(i<j) a[j--]=a[i]; //cover the a[j] } if(i==j) a[i]=tmp; quicksort(a,first,i-1); quicksort(a,i+1,last); } }缺点:
1.中枢值每次都选取为序列首元素。不能保证尽可能为中间值。
2.对于数据的排序而言,对于小数据而言,使用直接插入排序效果可能更好。
3.快速排序使用了两个递归调用,能不能进一步优化。
优化 从3方面进行:
1.选取中枢值。这里可以采用随机的方法,但是产生随机序列本身也要耗时,效果可能不好,从概率的角度来看,选取头,中,尾三处的值。然后取中间值。作为中枢值,效果较好。
/*********************************************************************** QuickSort optimized 1. optimize base value 2. optimize sort scale n 3. optimize the way of recusion (tail recursion) ***********************************************************************/ #include <iostream> #include <ctime> using namespace std; void Swap(int &x,int &y) { int tmp=x; x=y; y=x; } //Unoptimized QuickSort void quicksort(int a[],int first,int last) { while(first<last) { int i=first,j=last; int mid=(first+last)/2; //mid value if(a[first]>a[last]) Swap(a[first],a[last]); // ensure index pos=first value less than last if(a[mid]>a[last]) Swap(a[mid],a[last]); // ensure index pos=mid value less than last if(a[first]>a[mid]) Swap(a[first],a[mid]); // ensure first val less than mid int tmp=a[first]; //now a[first] is the mid-value of low -mid-high while( i<j ) { while(i<j && a[j]>=tmp) --j; // find the first index j that a[j] < tmp from right to left if(i<j) a[i++]=a[j]; // cover the a[i]. while( i<j && a[i]<tmp) i++; //find the first index i that a[i]>tmp from left to right if(i<j) a[j--]=a[i]; //cover the a[j] } if(i==j) a[i]=tmp; quicksort(a,first,i-1); first=i+1; //reduce one recursion //quicksort(a,i+1,last); } } void QuickSort(int a[],int len) { if(len>32) quicksort(a,0,len-1); //else // when data scale less than 32 use InsertSort // InsertSort(a,len); } void print(int a[],int len) { for(int i=0;i<len;i++) printf("%d ",a[i]); printf("\n"); } int main() { srand(time(NULL)); const int MAX=1000; int a[MAX]; for(int i=0;i<MAX;i++) a[i]=rand(); clock_t timebegin=clock(); QuickSort(a,MAX); clock_t timeend=clock(); //cout<<"优化排一千万个数耗时:\t"<<timeend-timebegin<<"ms"<<endl; print(a,MAX); }