如何优化合并排序和快速排序

 

和并排序和快速排序在元素的重复率特别高的时候排序的时间变长。我们可以利用三向切分的办法来避免相同的元素进行交换,以减少交换次数。

       具体如下图所示:

 

总共有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;
}

 

posted @ 2018-05-15 18:56  CMlhc  阅读(270)  评论(0编辑  收藏  举报