quicksort

Posted hankunyan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了quicksort相关的知识,希望对你有一定的参考价值。

复习quicksort的两种写法,pivot的选取不唯一,甚至可以随机选取,然后交换一下位置即可。两种方法的 partition 不一样,都很好理解。

quickselect 是找数组第k大的元素,本质和quicksort一样,partition函数共用,找第k个元素在的那一侧。需要注意递归的时候k需要根据情况变动。

quickselect时间复杂度 O(n),最坏情况O(n^2)。

 

写法一:当时学C++教的方法

以 a[low] 作为 pivot,每次循环先从右向左,再从左往右,填补空缺。最后 low==high,把 pivot 放到这个位置即可。

#include <iostream>

int partition(vector<int> &a, int low, int high){
    int pivot=a[low];
    while (low<high){
        while (low<high && a[high]>=pivot) --high;
        if (low<high) a[low++]=a[high];
        while (low<high && a[low]<=pivot) ++low;
        if (low<high) a[high--]=a[low];
    }
    a[low] = pivot;
    return low;
}

void quicksort(vector<int> &a, int low, int high){
    if (low>=high) return;
    int pivotIndex=partition(a,low,high);
    quicksort(a,low,pivotIndex-1);
    quicksort(a,pivotIndex+1,high);
}

int quickselect(vector<int> &a, int low, int high, int k){
    if (low==high) return a[low];
    int pivotIndex=partition(a,low,high);
    int len=pivotIndex-low+1;
    if (k==len) return a[pivotIndex];
    else if (k<len) return quickselect(a,low,pivotIndex-1,k);
    else return quickselect(a,pivotIndex+1,high,k-len);
}

int main() {
    vector<int> a={1,5,8,3,2};
    int n=a.size();
    quicksort(a,0,n-1);
    for (auto x:a) cout<<x<< ;
    cout << endl;
    for (int k=1;k<=n;++k) cout<<quickselect(a,0,n-1,k)<< ;
    return 0;
}

 

 

写法二:算法导论写法

以 a[high] 作为 pivot (用a[low]的话写起来稍作修改即可),然后一个 for 循环 low~high-1,遇到大的不管,遇到小的都放到前面。最后 pivot 放在小的元素后面即可。

#include <iostream>

int partition(vector<int> &a, int low, int high){
    int pivot=a[high];
    int k=low;
    for (int i=low;i<high;++i){
        if (a[i]<=pivot) swap(a[i],a[k++]);
    }
    swap(a[high],a[k]);
    return k;
}

void quicksort(vector<int> &a, int low, int high){
    if (low>=high) return;
    int pivotIndex=partition(a,low,high);
    quicksort(a,low,pivotIndex-1);
    quicksort(a,pivotIndex+1,high);
}

int quickselect(vector<int> &a, int low, int high, int k){
    if (low==high) return a[low];
    int pivotIndex=partition(a,low,high);
    int len=pivotIndex-low+1;
    if (k==len) return a[pivotIndex];
    else if (k<len) return quickselect(a,low,pivotIndex-1,k);
    else return quickselect(a,pivotIndex+1,high,k-len);
}

int main() {
    vector<int> a={1,5,8,3,2};
    int n=a.size();
    quicksort(a,0,n-1);
    for (auto x:a) cout<<x<< ;
    cout << endl;
    for (int k=1;k<=n;++k) cout<<quickselect(a,0,n-1,k)<< ;
    return 0;
}

 

 

reference:

https://segmentfault.com/a/1190000002651247

https://www.geeksforgeeks.org/quickselect-algorithm/

http://www.sourcetricks.com/2011/06/quick-select.html#.W-JG23r0nRZ

以上是关于quicksort的主要内容,如果未能解决你的问题,请参考以下文章

快速排序 QuickSort

poj 2299 Ultra-QuickSort 逆序对模版题

java Heapsort实现和一些基准代码。 mergesort或quicksort的实现速度相当慢..

快速排序(QuickSort),归并排序(MergeSort),堆排序(HeapSort)典型C++代码实现总结

QuickSort

POJ2299 Ultra-QuickSort