zoukankan      html  css  js  c++  java
  • 如何优化合并排序和快速排序

     

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

           具体如下图所示:

     

    总共有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;
    }
  • 相关阅读:
    python通过帐号和密码访问mysql
    pyqt5简单登陆界面
    PyQt5点击按钮产生新窗体
    ubuntu访问win10下的磁盘
    python平均值和加权平均值
    牛顿迭代法求高次方程的根
    运用模逆运算(同余方程)来解决Matlab课上的一道思考题
    线程实现方式与临界区保护
    线程调度的问题:Lock Convoy(锁封护)与Priority Inversion(优先级反转)
    C++ lvalue,prvalue,xvalue,glvalue和rvalue详解(from cppreference)
  • 原文地址:https://www.cnblogs.com/CMlhc/p/9042561.html
Copyright © 2011-2022 走看看