排序算法(快速排序)
快速排序是一個分治過程:
對于數組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 20template<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);} }其運行結果如下
轉載于:https://www.cnblogs.com/xiao-cheng/archive/2011/10/05/2199190.html
總結
以上是生活随笔為你收集整理的排序算法(快速排序)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于Linux系统中用户权限问题
- 下一篇: 《模式识别与机器学习》学习笔记:2.2