码迷,mamicode.com
首页 > 其他好文 > 详细

quicksort

时间:2018-11-07 11:39:19      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:com   quic   复杂度   vector   target   quicksort   span   org   for   

复习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

标签:com   quic   复杂度   vector   target   quicksort   span   org   for   

原文地址:https://www.cnblogs.com/hankunyan/p/9920770.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!