排序---快速排序

快速排序

1. 快速排序

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

 

快速排序
Sorting quicksort anim.gif
使用快速排序法对一列数字进行排序的过程
分类 排序算法
数据结构 不定
最坏时间复杂度 \Theta (n^{2})
最优时间复杂度 \Theta (n\log n)
平均时间复杂度 \Theta (n\log 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]

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

posted on 2018-10-24 21:43  wangzhch  阅读(835)  评论(1编辑  收藏  举报

导航