在個人上一篇博客中(https://www.cnblogs.com/algorithm-process/p/11963856.html),咱們提到了快速排序劃分的三鍾方法,在快速排序中,咱們但願對序列進行劃分時,能將一個序列進行兩等分,可是咱們在使用時始終選取第一個元素爲基準值,這樣就會致使在一些狀況(好比是降序排列的序列)下,沒法將序列進行等分或是近似等分。若是咱們每次選擇基準值是一箇中間值是否是能儘量的將待排序的序列作到一個趨近於等分的狀況呢?接下來就是由這種思想而提出的優化方法。html
思想:在左邊界p,右邊界r和中間下標mid所表明的元素之間選擇一個做爲基準點,選擇方法爲找到這三個值中中間那個做爲基準點。數組
代碼以下:優化
1 int partition(int a[],int p,int r){ 2 //選取一個基準點 3 int midIndex= p+((r-p)>>1);//中間下標 4 int midValue=-1;//中間值下標 5 if(a[p]<=a[midIndex]&&a[p]>=a[r]) midValue=p; 6 else if(a[r]<=a[midIndex]&&a[r]>=a[p]) midValue=r; 7 else midValue=midIndex; 8 swap(a[midValue],a[p]); 9 10 int x=a[l];//基準點 11 int l=p+1,q=r; 12 while(l<=q){ 13 while(a[l]<=x&&l<=q) ++l; 14 while(a[q]>x&&l<=q) --q; 15 if(l<=q) swap(a[l],a[q]); 16 } 17 swap(a[p],a[q]); 18 return q; 19 }
在這三個點中找中間值做爲基準點在某些狀況下也並不能表明整個序列的中間值,爲了能獲得一個真正的中間值,咱們在此基礎上又提出了進一步求中間值的方法。ui
思想:將一個數組分紅每五個元素一組,若最後一組元素不足五個,也做爲一組。而後使用一個數組來存儲每一個劃分中的中間值,獲得每一個劃分的中間值後,取這個數組的中間值,即爲所求的中間值。spa
獲得中間值的代碼以下:code
1 void insertsort(int a[],int p,int q){//插入排序 2 int temp; 3 for(int i=p;i<=q;i++){ 4 if(a[i]<a[i-1]){ 5 temp=a[i]; 6 for(int j=i;j>=0;j--){ 7 if(j>0&&a[j-1]>temp) a[j]=a[j-1]; 8 else { 9 a[j]=temp; 10 break; 11 } 12 } 13 } 14 } 15 } 16 int getmid(int a[],int p,int r){ 17 int length=r-p+1; 18 int grouplength=(length%5==0)?(length/5):(length/5+1);//每五個元素一組,獲得劃分的個數 19 int *medians=new int[grouplength];//定義存儲中間值的數組 20 int midIndex=0; 21 for(int i=0;i<grouplength;i++){ 22 if(i==grouplength-1){//最後一組時 ,須要單獨處理,由於這組中元素個數小於5個 23 insertsort(a,p+j*5,r);//調用插入排序 24 medians[midIndex++]=a[(p+j*5+r)/2];//存入數組 25 }else { 26 insertsort(a,p+j*5,p+j*5+4); 27 medians[midIndex++]=a[(p+j*5+2)]; 28 } 29 } 30 insertsort(mediams,0,grouplength-1); 31 return medians[grouplength/2]; 32 }
這種方法獲得中間值的時間複雜度爲O(n),可是一般咱們並不使用它,更多的是使用三點中值法。htm
思想:雖然說插入排序的時間複雜度爲O(n2),可是其實是:n(n-1)/2。快速排序的時間複雜度爲O(nlogn),其實是:n(logn+1)。通過計算後發現當n<=8時,插入排序所消耗的時間是少於快速排序的。blog
通過優化後的代碼是:排序
1 quicksort(int a[],int l,int r){//快排遞歸形式 2 if(l<r){ 3 if((r-l+1)<=8) insertsort(a,l,r);//調用插入排序 4 else{ 5 int q=partition(a,l,r);//找到中間數,不必定是中位數 6 quicksort(a,l,q-1); 7 quicksort(a,q+1,r); 8 } 9 } 10 }
上述就是比較經常使用的三種優化方法了。遞歸