排序算法(快速排序)
2011-10-05 00:01
190 查看
快速排序是一个分治过程:
对于数组A[p….r]选取A中的一个元素A(q),按照大小将A分成两部分 A[p…q-1] 和 A[q….r]
其中 A[p…q-1] 中所有的元素都小于A(q),而 A[q….r]中所有元素都大于 A(q).
对于划分后的数组依然采用同样的方法分裂。注意分裂后的数组可以为空,如此进行下去直到
分裂后的元素不超过一个,这将所有的小数组合并在一起就是排好序的。
递归算法如下:
quicksort(A,p,r)
if p<r
then q=partition(A,p,r)
quicksort(A,p,q-1)
quicksort(A,q,r)
算法的关键是对数组的分裂,下面用图示显示分裂过程
不妨取选取A的最后一个元素为比较元素A(q)=A[r]
用 p 记录起点,r 记录终点,j 记录当前还未做比较的起点位置,i 记录当前做完比较的分界点,即小数组的最后一个位置
(1) 比较A[j]和A[r]的大小,
如果A[j]<=A[r] 则交换A[j]和A[i+1],j++,i++ (A[j]在小数组位置)
否则,j++, (A[j]在大数组位置)
(2) 当 j = r 时,说明所有点都以比较,此时交换 A[i+1] 和 A[r] ,返回 i +1 即可
如果数组本身已经按照从小到大排好了序,可以想见其算法复杂度很高,这是最坏的情况,
这相当于每两个元素之间都要相比较,则复杂度是
\sum_{ i=1 }^n ( n-i ) = n(n-1)/2 = O(n^2) 很大 (堆排序是 O(nlogn))
最好的情况是每次都二分,算法复杂度是
T(n) = 2T(n/2) + O(n)
不妨令 n=2^k, O(n)=Cn, C为常数
则T(n) = 2T(2^{k-1})+Cn = 2( 2T(2^{k-2})+Cn/2)+Cn = 2^2T(2^{k-2})+2Cn
=………=2^k T(1)+Ckn = nT(1)+Cnlogn = O(nlogn) .
算法的复杂度当然是每次划分的程度有关,希望大小子树比例接近与1:1.
下面使用随机化的快速排序算法,其期望复杂度是 O(nlogn) 还是不错的:
其运行结果如下
对于数组A[p….r]选取A中的一个元素A(q),按照大小将A分成两部分 A[p…q-1] 和 A[q….r]
其中 A[p…q-1] 中所有的元素都小于A(q),而 A[q….r]中所有元素都大于 A(q).
对于划分后的数组依然采用同样的方法分裂。注意分裂后的数组可以为空,如此进行下去直到
分裂后的元素不超过一个,这将所有的小数组合并在一起就是排好序的。
递归算法如下:
quicksort(A,p,r)
if p<r
then q=partition(A,p,r)
quicksort(A,p,q-1)
quicksort(A,q,r)
算法的关键是对数组的分裂,下面用图示显示分裂过程
不妨取选取A的最后一个元素为比较元素A(q)=A[r]
用 p 记录起点,r 记录终点,j 记录当前还未做比较的起点位置,i 记录当前做完比较的分界点,即小数组的最后一个位置
(1) 比较A[j]和A[r]的大小,
如果A[j]<=A[r] 则交换A[j]和A[i+1],j++,i++ (A[j]在小数组位置)
否则,j++, (A[j]在大数组位置)
(2) 当 j = r 时,说明所有点都以比较,此时交换 A[i+1] 和 A[r] ,返回 i +1 即可
如果数组本身已经按照从小到大排好了序,可以想见其算法复杂度很高,这是最坏的情况,
这相当于每两个元素之间都要相比较,则复杂度是
\sum_{ i=1 }^n ( n-i ) = n(n-1)/2 = O(n^2) 很大 (堆排序是 O(nlogn))
最好的情况是每次都二分,算法复杂度是
T(n) = 2T(n/2) + O(n)
不妨令 n=2^k, O(n)=Cn, C为常数
则T(n) = 2T(2^{k-1})+Cn = 2( 2T(2^{k-2})+Cn/2)+Cn = 2^2T(2^{k-2})+2Cn
=………=2^k T(1)+Ckn = nT(1)+Cnlogn = O(nlogn) .
算法的复杂度当然是每次划分的程度有关,希望大小子树比例接近与1:1.
下面使用随机化的快速排序算法,其期望复杂度是 O(nlogn) 还是不错的:
// quicksort.cpp : 定义控制台应用程序的入口点。 // //此程序为快速排序算法和随机化版本,原理是每次将向量分成大小两堆 //2011/3/25 肖成 #include <vector> #include <iostream> using namespace std; #define N 20 template<class T> int partition(vector<T>& A, int p, int r); template<class T> void quicksort(vector<T>& A, int p, int r); template<class T> int random_partition(vector<T>& A, int p, int r); template<class T> void random_quicksort(vector<T>& A, int p, int r); int main() { double a[]={2,4,3,5,8,7,9,0,11,15,23,32,12,16.4,32,23,2.8,1,42,6,8}; cout<<"The original vector is :"<<endl; for(int i=0;i<N+1;i++) cout<<a[i]<<" "; cout<<endl; cout<<"-----------------------------------------------------------------------------------"<<endl; vector<double> vec(a,a+N+1); vector<double>::iterator iter; cout<<"quicksort"<<endl; cout<<"-----------------------------------------------------------------------------------"<<endl; quicksort(vec,0,N); for(iter=vec.begin();iter!=vec.end();iter++) cout<<*iter<<" "; cout<<endl; cout<<"random_quicksort"<<endl; cout<<"-----------------------------------------------------------------------------------"<<endl; vector<double> vecrand(a,a+N+1); random_quicksort(vecrand,0,N); for(iter=vecrand.begin();iter!=vecrand.end();iter++) cout<<*iter<<" "; cout<<endl; return 0; } template<class T> int partition(vector<T>& A, int p, int r) { T x=A[r]; int i=p-1; for(int j=p;j<=r-1;j++) { if(A[j]<=x) { i=i+1; T temp=A[i]; A[i]=A[j]; A[j]=temp; } } A[r]=A[i+1]; A[i+1]=x; return i+1; } template<class T> void quicksort(vector<T>& A, int p, int r) { if(p<r) { int q=partition(A,p,r); quicksort(A,p,q-1); quicksort(A,q+1,r); } } template<class T> int random_partition(vector<T>& A, int p, int r) { int i=rand()%(r-p)+p; T temp=A[r]; A[r]=A[i]; A[i]=temp; return partition(A,p,r); } template<class T> void random_quicksort(vector<T>& A, int p, int r) { if(p<r) { int q=random_partition(A,p,r); random_quicksort(A,p,q-1); random_quicksort(A,q+1,r); } }
其运行结果如下
相关文章推荐
- 排序算法之快速排序
- 排序算法之快速排序(quick_sort)
- 排序算法之快速排序
- 排序算法之快速排序(QuickSort)
- 排序算法:快速排序
- 排序算法(六)快速排序
- PHP排序算法之快速排序(Quick Sort)及其优化算法详解
- C#实现所有经典排序算法(选择排序 冒泡排序 快速排序)
- 排序算法之快速排序
- 排序算法之快速排序
- 排序算法——快速排序
- 【排序算法】快速排序原理及Java实现
- 排序算法之快速排序
- php排序算法(冒泡排序,快速排序)
- 排序算法之快速排序
- 常见的排序算法(三) 交换排序(冒泡排序,快速排序)
- 八种排序算法Java实现-快速排序
- 算法 排序算法--快速排序
- 必须知道的八大种排序算法【java实现】(一) 冒泡排序、快速排序
- 排序算法之-快速排序