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的主要内容,如果未能解决你的问题,请参考以下文章
poj 2299 Ultra-QuickSort 逆序对模版题
java Heapsort实现和一些基准代码。 mergesort或quicksort的实现速度相当慢..