快速排序是一种比较实用的排序算法,平均时间复杂度为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