1. 程式人生 > >如何優化合並排序和快速排序

如何優化合並排序和快速排序

info nbsp 快速排序 結束 template 如何 技術 size pac

和並排序和快速排序在元素的重復率特別高的時候排序的時間變長。我們可以利用三向切分的辦法來避免相同的元素進行交換,以減少交換次數。

具體如下圖所示:

技術分享圖片

總共有3個指針,lt,i,和gt,這個三個指針分別指著隊首,隊首的下一位,隊尾。以隊首為參考點,設該數組為a。設中間變量temp.

temp ← a[lt] //隊首設為參考變量
if a[i] < temp:
          swap(a,lt++,i++)
else if a[i] > temp:
          swap(a,i,j--)
else 
          i++
如果lt的值和i的值隨著移動,到最後結束的時候,lt的左邊的值一定是比temp小的值,gt右邊的值一定是比temp大的值,中間lt 和 gt 之間的值是相等的,最後可以免去交換。遞歸交換後,後面的遞歸表達式為
               sort(a,begin,lt-1)
               sort(a,gt+1,end)
如果中間有重復的元素,最後面的各個指針所指的位置如下:

技術分享圖片


所以第一個遞歸的sort中用lt-1的優化會比較快,用lt也可以執行。
代碼示例:
#include <iostream>
using namespace std;
template <typename T>
void sawp(T a[],int first,int second){
    T temp;
    temp = a[first];
    a[first] = a[second];
    a[second] 
= temp; } template <typename T> int sort(T a[],int low,int high){ if(low < high){ int lt = low,i=low+1,gt = high; int temp = a[low]; while(i <= gt){ if(a[i] < temp){ sawp(a,lt++,i++); }else if(a[i] > temp){ sawp(a,i,gt
--); }else{ i++; } } cout<<"sort("<<"a,"<<low<<","<<high<<")"<<endl; cout<<"lt="<<lt<<",i="<<i<<",gt="<<gt<<endl; for (int j = 0; j < 13; ++j) { cout << a[j] << " "; } cout<<endl; sort(a,low,lt); sort(a,gt+1,high); } } int main() { int c[] = {2,2,2,2,2,0,0,0,0,0,0,1,5}; int a[] = {1,2,3,4,5,5,5,5,9,10,11,12,13}; int b[] = {13,12,11,10,9,8,7,6,5,4,3,2,1}; //int a[] = {2,0,1,5}; int len = sizeof(b)/sizeof(int); sort(b,0,len-1); //for (int i = 0; i < len; ++i) //cout << a[i] << " "; cout << endl; }

如何優化合並排序和快速排序