快速排序是一種比較實用的排序算法,平均時間複雜度爲O(nlogn),最壞狀況爲O(n*n),最好狀況也是O(nlogn)。該算法基於分治處理思想,在數列中選取一個主元,根據這個主元把整個數列分爲兩部分:一部分比這個主元小,一部分比這個主元大。而後對這兩部分分別再選取主元劃分,以此遞歸下去。算法
針對一個A[p....r]的數組,其執行步驟能夠描述爲:數組
一、分組:A[p..r]被劃分爲兩個可能爲空的子數組A[p..q-1]和A[q+1..r],使得A[p..q-1] <= A[q] <= A[q+1..r];ui
二、解決:經過遞歸調用快速排序,對子數組A[p..q-1]和A[q+1..r]排序。spa
三、合併。.net
快速排序的關鍵是實現分組(partion),此過程有多種實現方法。主元能夠分別選取首、尾,或者使用三數取中法。數組掃描方向又能夠單向掃描和雙向掃描。另外,藉助棧結構,還有非遞歸版本的實現。code
目前,本身分析實現了的版本以下:blog
一、尾數做爲主元,從前日後單向掃描排序
貌似此版本是《算法導論》裏的實現版本,具體我也沒看過,好多博客裏都這樣說。僞代碼以下:遞歸
QUICKSORT(A, p, r) if p < r then q ← PARTITION(A, p, r) QUICKSORT(A, p, q - 1) QUICKSORT(A, q + 1, r)關鍵的分組過程:
PARTITION(A, p, r) x ← A[r] i ← p - 1 for j ← p to r - 1 do if A[j] ≤ x then i ← i + 1 exchange A[i] <-> A[j] exchange A[i + 1] <-> A[r] return i + 1具體實現:
int partionLast(int arr[], int p, int r){ int x = arr[r]; int i = p - 1; int j, tmp; for(j = p; j < r ; j++){ if(arr[j] <= x){ i++; tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } } tmp = arr[i+1]; arr[i+1] = arr[j]; arr[j] = tmp; return i+1; }
<pre name="code" class="cpp"> void quicksort(int arr[], int p, int r){ if(p<r){ int q = partionLast(arr,p,r); quicksort(arr,p,q-1); quicksort(arr,q+1,r); } }二、第一個數做爲主元,從前日後單向掃描
int partionFirst(int arr[], int p, int r){ int x = arr[p]; int i = p; int j,tmp; for(j = p+1; j <= r; j++){ if(arr[j] <= x){ i++; tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } } tmp = arr[i]; arr[i] = arr[p]; arr[p] = tmp; return i; }三、尾數做主元,雙向掃描
int partionDoubleEnded(int arr[], int p, int r){ int x = arr[r]; int i = p; int j = r - 1; int tmp; do{ if(arr[i] <= x){ i++; }else{ if(arr[j] >= x){ j--; }else{ tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; i++; } } }while(i <= j&&j >= p); tmp = arr[i]; arr[i] = arr[r]; arr[r] = tmp; return i; }
template<typename Comparable> void quicksort2(vector<Comparable> &vec,int low,int high){ stack<int> st; if(low<high){ int mid=partition(vec,low,high); if(low<mid-1){ st.push(low); st.push(mid-1); } if(mid+1<high){ st.push(mid+1); st.push(high); } //其實就是用棧保存每個待排序子串的首尾元素下標,下一次while循環時取出這個範圍,對這段子序列進行partition操做 while(!st.empty()){ int q=st.top(); st.pop(); int p=st.top(); st.pop(); mid=partition(vec,p,q); if(p<mid-1){ st.push(p); st.push(mid-1); } if(mid+1<q){ st.push(mid+1); st.push(q); } }
http://blog.csdn.net/v_july_v/article/details/6116297ip
http://blog.csdn.net/v_JULY_v/article/details/6211155
http://blog.csdn.net/v_JULY_v/article/details/6262915