• 排序---快速排序


    快速排序

    1. 快速排序

    快速排序(Quicksort),又称划分交换排序(partition-exchange sort),简称快排,一种排序算法,最早由东尼·霍尔提出。在平均状况下,排序n个项目要O(nlogn)次比较。在最坏状况下则需要O(n2)次比较,但这种状况并不常见。事实上,快速排序O(nlogn)通常明显比其他算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地达成。详情见快速排序【维基百科】 

     

    快速排序
    Sorting quicksort anim.gif
    使用快速排序法对一列数字进行排序的过程
    分类 排序算法
    数据结构 不定
    最坏时间复杂度 Theta (n^{2})
    最优时间复杂度 Theta (nlog n)
    平均时间复杂度 Theta (nlog n)
    最坏空间复杂度 根据实现的方式不同而不同

    2. 快速排序(基础版)

    #include<iostream>
    #include<vector>
    #include <stdlib.h>
    #include <time.h>
    using namespace std;
    
    int Partition(vector<int> &array, int low, int high){
        int pivotkey = array[low]; // 优化点1
        while(low<high){
            while(low<high && array[high] >= pivotkey)
                high--;
            swap(array[low], array[high]); // 优化点2
            while(low<high && array[low] <= pivotkey)
                low++;
            swap(array[low], array[high]);
        }
        return low;
    }
    
    void QSort(vector<int> &array, int low, int high){
        int pivot;
        if(low<high){ // 优化点3
            pivot = Partition(array, low, high);
            QSort(array, low, pivot-1);
            QSort(array, pivot+1, high);
        }
    }
    
    void QuickSort(vector<int> &array){
        QSort(array, 0, array.size()-1);
    }
    
    // 判断array是否有序
    bool isOrder(vector<int> &array){
        for(int i = 1; i < array.size(); i++){
            if(array[i] < array[i-1])
                return false;
        }
        return true;
    }
    
    // 生成n个介于min,max之间的整型数
    vector<int> RAND(int max, int min, int n) {
        vector<int> res;
        //srand(time(NULL)); // 注释该行之后,每次生成的随机数都一样
        for(int i = 0; i < n; ++i) {
            int u = (double)rand() / (RAND_MAX + 1) * (max - min) + min;
            res.push_back(u);
        }
        return res;
    }
    
    int main(int argc, char const *argv[]) {
        vector<int> a = RAND(1, 10000, 20000000);
    
        clock_t start = clock();
        QuickSort(a);
        clock_t end   = clock();
        cout << "Time goes: " << (double)(end - start) / CLOCKS_PER_SEC << "sec" << endl;
    
        bool sorted = isOrder(a);
        cout<<sorted<<endl;
        return 0;
    }

    使用 20000000(2千万)个介于1, 10000之间的数字进行测试,运行结果如下:

    Time goes: 75.315sec
    1
    [Finished in 77.9s]

     

    3. 快速排序(优化版)

    #include<iostream>
    #include<vector>
    #include <stdlib.h>
    #include <time.h>
    #include <ctime>
    using namespace std;
    
    int Partition(vector<int> &array, int low, int high){
        // 优化1:使用三数区中法,有效避免pivotkey取得最大最小值
        int mid = low + (high - low) / 2;
        if(array[low] > array[high])
            swap(array[low], array[high]);
        if(array[mid] > array[high])
            swap(array[mid], array[high]);
        if(array[mid] > array[low])
            swap(array[mid], array[low]);
    
        int pivotkey = array[low];
        while(low < high){
            while(low < high && array[high] >= pivotkey)
                high--;
            array[low] = array[high]; // 优化2:采用指定位置赋值,减少不必要的交换
            while(low < high && array[low] <= pivotkey)
                low++;
            array[high] = array[low];
        }
        array[low] = pivotkey;
        return low;
    }
    
    void InsertSort2(vector<int> &array, int low, int high){
        for(int i = low+1; i <= high; i++){
            if(array[i] < array[i-1]){
                int temp = array[i];
                int j = i;
                while(j > low && temp < array[j-1]){
                    array[j] = array[j-1];
                    j--;
                }
                array[j] = temp;
            }
        }
    }
    
    void QSort(vector<int> &array, int low, int high){
        int pivot;
        if((high-low) > 13){
            pivot = Partition(array, low, high);
            QSort(array, low, pivot-1);
            QSort(array, pivot+1, high);
        }
        // 优化3:当元素部分有序时,切换到插入排序
        else
            InsertSort2(array, low, high);
    }
    
    bool isOrder(vector<int> &array){
        for(int i = 1; i < array.size(); i++){
            if(array[i] < array[i-1])
                return false;
        }
        return true;
    }
    
    void QuickSort(vector<int> &array){
        QSort(array, 0, array.size()-1);
    }
    
    // 生成n个介于min,max之间的整型数
    vector<int> RAND(int max, int min, int n) {
        vector<int> res;
        //srand(time(NULL)); // 注释该行之后,每次生成的随机数都一样
        for(int i = 0; i < n; ++i) {
            int u = (double)rand() / (RAND_MAX + 1) * (max - min) + min;
            res.push_back(u);
        }
        return res;
    }
    
    int main(int argc, char const *argv[]) {
        vector<int> a = RAND(1, 10000, 20000000);
    
        clock_t start = clock();
        QuickSort(a);
        clock_t end   = clock();
        cout << "Time goes: " << (double)(end - start) / CLOCKS_PER_SEC << "sec" << endl;
    
        bool sorted = isOrder(a);
        cout<<sorted<<endl;
        return 0;
    }

    使用相同的数字进行测试,运行结果如下:

    Time goes: 64.458sec
    1
    [Finished in 66.9s]

    点击此处查看常用排序算法

  • 相关阅读:
    (转) Nova是如何统计OpenStack资源
    (转) 一次批量重启引发的Neutron网络故障
    (转)理解Keystone的四种Token
    neutron 虚拟机网络问题调试
    转 Nova: 虚机的块设备总结 [Nova Instance Block Device]
    kvm 客户机系统的代码是如何运行的
    12 while循环
    11猜拳游戏
    10 if 嵌套
    09 if...elif..else语句
  • 原文地址:https://www.cnblogs.com/iwangzhengchao/p/9846397.html
Copyright © 2020-2023  润新知