快速排序
快速排序使用了分治思想。
分解:数组A[p..r]被划分为两个(可能为空)子数组A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每一个元素都小于等于A[q],而A[q]也小于等于A[q+1..r]中的每个元素。其中,计算下标q也是划分过程的一部分。
解决:通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]进行排序。
合并:因为子数组都是原址排序的,所以不需要合并操作,数组A[p..r]已经有序。
快速排序过程:
void quickSort(int A[],int p,int r) { if(p<r) { int q=Partition(A,p,r); quickSort(A,p,q-1); quickSort(A,q+1,r); } }
数组的划分
算法的关键过程是Partition过程,它实现了对子数组A[p..r]的原址重排。
int Partition(int A[],int p,int r) { int x=A[r]; int i=p-1; for(int j=p;j<=r-1;j++) { if(A[j]<=x) { i++; int tmp=A[i]; A[i]=A[j]; A[j]=tmp; } } int tmp=A[i+1]; A[i+1]=A[r]; A[r]=tmp; return (i+1); }
Partition总是选择一个x=A[r]作为主元,并围绕它来划分子数组A[p..r]。随着程序的执行,数组被划分为四个区域。
在循环体中,每一轮迭代开始时,对于任意数组下标i,有:
1、若p<=k<=i,则A[k]<=x;
2、若i+1<=k<=j-1,则A[k]>x;
3、若k=r,则A[k]=x。


随机化版本
前面始终采用A[r]作为主元,随机抽样是从子数组A[p..r]中随机选择一个元素作为主元。在子序列中随机选出一个元素,然后与A[r]互换,剩余部分与之前相同。
浙公网安备 33010602011771号