• 排序算法


    关于C++各类排序算法与std::sort性能的比较

    https://blog.csdn.net/qq_24625045/article/details/49964173

    堆排序

    堆排序分为初始构建堆和重建堆两部分内容。

    构建堆。

    从顺序表构建堆,时间复杂度O(n)。每个非终端节点最多进行2次比较和互换。

    重建堆。

    重建堆需要取 n-1 次堆顶记录。第i次取堆顶记录重建堆,需要进行 logi 次比较和互换,耗时O(logi)(完全二叉树的某个节点到根节点的距离是 [logi]+1)。因此重建堆的时间复杂度为O(nlogn)。

    总体来看,堆排序的时间复杂度为O(nlogn)。堆排序对原始记录不敏感,所以最好、最坏情况都是O(nlogn)。

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    typedef struct
    {
        vector<int> r = {0};
        int length;
    } SqList;
    
    void swap(SqList *L, int i, int j) {
        int temp = L->r[i];
        L->r[i] = L->r[j];
        L->r[j] = temp;
    }
    
    void HeapAdjust(SqList *L, int index, int len) {
        
        int temp = L->r[index];
        
        for(int i = index*2; i <= len; i*2) {
            if(i < len && L->r[i] < L->r[i+1])
                i++;
            
            if(temp >= L->r[i])
                break;
            else {
                swap(L, index, i);            
                index = i;
            }
        }
        
    }
    
    void HeapSort(SqList *L) {
        if(L ==NULL)
            return;
        
        int len = L->length;
        
        for(int i = (len/2); i > 0; --i) {
            HeapAdjust(L, i, len);
        }
        
        for(int j = len; j > 1; --j) {
            swap(L, 1, j);
            HeapAdjust(L, 1, j-1);
        }
    }
    
    int main (int argc, char** argv) {
        SqList *sl = new SqList;
        
        int m, n;
        cin >> n;
        
        sl->length = n;
        
        for(int i = 1; i <= n; ++i) {
            cin >> m;
            sl->r.push_back(m);
        }
        
        HeapSort(sl);
        
        for (int i = 0; i <= n; ++i) {
            cout << sl->r[i] << endl;
        }
        
        return 0;
    }

    快速排序

    平均时间复杂度O(nlogn);

    最好情况时间复杂度O(nlogn),pivotkey基本处于顺序表中间;

    最坏情况时间复杂度O(n^2),顺序表处于正序和倒序;

    最好情况空间复杂度O(logn),要执行logn次递归调用;

    最坏情况空间复杂度O(n),要执行n-1次递归调用;

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    typedef struct {
        vector<int> r = {0};
        int length;
    } SqList;
    
    void swap(SqList * L, int i, int j) {
        int temp = L->r[i];
        L->r[i] = L->r[j];
        L->r[j] = temp;
    }
    
    int getPivot(SqList *L, int low, int high) {
        int pivot = L->r[low];
       
        while(low < high) {
            while(low < high && pivot <= L->r[high]) {
                high --;
            }
            swap (L, low, high);
            
            while(low < high && pivot > L->r[low]) {
                low ++;
            }
            swap (L, low, high);        
        }
        return low;
    }
    
    void QSort(SqList *L, int low, int high) {    
        if(low < high) {
            int pivot = getPivot(L, low, high);
            QSort(L, low, pivot-1);
            QSort(L, pivot+1, high);
        }
    }
    
    void QuickSort (SqList *L) {
        QSort(L, 1, L->length-1);
    }
    
    int main (int argc, char** argv) {
        SqList *sl = new SqList;
        
        int num = 0, temp = 0;
        
        cout << "cin the number of sqlist(include flag)" << endl;
        cin >> num;
        sl->length = num;
        
        for(int i = 0; i < num-1; ++i) {
            cin >> temp;
            sl->r.push_back(temp);
        }
    
        QuickSort(sl);
        
        for(int i = 0; i < num; ++i)
            cout << sl->r[i] << endl;
        
        return 0;
    }

    对上述快速排序的改进:

    1)优化选取pivotkey。采用三数取中法获取pivotkey,而不是取左边界的数。

    2)优化不必要的交换。选取pivotkey后,将序列分成左右端序列,去除对pivotkey的移位操作。

    3)优化小数组的排序方案。当需要排序的数组长度小于某个阈值后,采用直接插入排序。因为快速排序用到了递归操作,在大量数据排序时,这点性能影响对整体算法优势而言可以忽略不计。直接插入排序适用于小量数据的排序,最好情况下时间复杂度为O(n)。

    4)优化递归操作。在下列代码中还未实施。

    #include <iostream>
    #include <vector>
    #include <ctime>
    
    using namespace std;
    
    clock_t start1, end1;
    
    #define MAX_LENGTH_INSERT_SORT 7
    
    typedef struct {
        vector<int> r = {0};
        int length;
    } SqList;
    
    void swap(SqList * sq, int left, int right) { // avoid to use the swap func in Partition func.
        int temp = sq->r[left];
        sq->r[left] = sq->r[right];
        sq->r[right] = temp;
    }
    
    int Partition(SqList * sq, int low, int high) {
        int mid = 0.5*(low+high);  // choose pivotkey in 3 data, low-mid-high
        
        if(sq->r[low] > sq->r[high])
            swap(sq, low, high);
        if(sq->r[mid] > sq->r[high])
            swap(sq, mid, high);
        if(sq->r[mid] > sq->r[low])
            swap(sq, low, mid);
        
        sq->r[0] = sq->r[low];
        
        while(low < high) {
            
            while(low < high && sq->r[0] <= sq->r[high])
                high --;
            sq->r[low] = sq->r[high];
            
            while(low < high && sq->r[0] >= sq->r[low])
                low ++;
            sq->r[high] = sq->r[low];
            
        }
        sq->r[low] = sq->r[0];
        return low;
    }
    
    void InsertSort(SqList * sq, int low, int high) {
        int temp;
        
        for(int i = low+1; i <= high; ++i) {
            if( sq->r[i] < sq->r[i-1] ) {
                temp = sq->r[i];
                
                int j;
                for(j = i-1; (sq->r[j] > temp) && (j>=low); --j ) {
                    sq->r[j+1] = sq->r[j];
                }
                
                sq->r[j+1] = temp;
            }
        }
    }
    
    void Sort(SqList * sq, int low, int high) {    
        int pivotkey;
        
        if( (high-low) > MAX_LENGTH_INSERT_SORT ) {
            pivotkey = Partition(sq, low, high);
            
            Sort(sq, low, pivotkey-1);
            Sort(sq, pivotkey+1, high);
        }
        else  // length is too small, use insert sort
            InsertSort(sq, low, high);
    }
    
    void QuickSort(SqList * sq) {
        Sort(sq, 1, sq->length);
    }
    
    
    int main (int argc, char** argv) {
        SqList *sl = new SqList;
        
        int num = 0, temp = 0;
        
        cout << "cin the number of SqList" << endl;
        cin >> num;
        sl->length = num;
        
        for(int i = 0; i < num; ++i) {       
            cin >> temp;
            sl->r.push_back(temp);
        }
    
        start1 = clock();
        QuickSort(sl);
        end1 = clock();
        
        cout << "cost time = " << (double)(end1 - start1) / CLOCKS_PER_SEC << endl;
        
        cout << "*************" << endl;
        
        for(int i = 1; i <= num; ++i)
            cout << sl->r[i] << endl;
        
        return 0;
    }
  • 相关阅读:
    页面登陆系统--带文字验证码
    Django-form表单
    Ajax 异步局部刷新
    Django认证系统auth认证
    cookie与session
    使用lorem在HTML中生成随机文本
    request模块
    java——第五天-面向对象OOP
    java——第四天
    java——第三天
  • 原文地址:https://www.cnblogs.com/gdut-gordon/p/11506296.html
Copyright © 2020-2023  润新知