快速排序的分治策略:
1. 划分: 选定一个记录作为轴值,以轴值为基准将整个序列划分为两个子序列r1...ri-1和ri+1...rn,轴值的位置i在划分的过程中确定,并且前一个子序列中的记录均小于或等于轴值,后一个子序列中的记录均大于或等于轴值。
[r1 ... ri-1] ri [ri+1 ... rn]
均<=ri ^ 均>=rn
轴值
位于最终位置
2. 求解子问题:分别对划分后的每一个子序列递归处理
3. 合并:由于对子序列r1...ri-1和ri+1...rn的排序是就地进行的,所以合并不需要执行任何操作。
public static int partition(int r[],int first,int end) {//划分
int i=first,j=end; //初始化待划分区间,选取第一个为轴值
while(i<j) {
while(i<j && r[i]<=r[j]) j--; //右侧扫描
if(i<j)
{
int temp=r[i];
r[i]=r[j];
r[j]=temp;
i++;
}
while(i<j && r[i]<=r[j]) i++; //左侧扫描
if(i<j) {
int temp=r[i];
r[i]=r[j];
r[j]=temp;
j--;
}
}
return i;
}
public static void quickSort(int r[],int first,int end) { //快速排序
int pivot;
if(first<end) {
pivot=partition(r,first,end);
quickSort(r,first,pivot-1); //左子序列
quickSort(r,pivot+1,end); //右子序列
}
}
补充一个另外一种想法(选取了不同轴值)的算法:
public static int partition(int[] a,int low,int high) {
int pivot = a[high];
int i = low - 1;
int temp;
for(int j=low;j<high;j++)
{
if(a[j]<=pivot)
{
i=i+1;
// exchange a[i] with a[j]
temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
temp = a[high];
a[high] = a[i+1];
a[i+1] = temp;
return i + 1;
}
public static void quickSort(int[] a,int low,int high)
{
int pivot;
if(low<high)
{
pivot = partition(a,low,high);
quickSort(a,low,pivot-1);
quickSort(a,pivot+1,high);
}
}
在最好的情况下,两种算法时间复杂度都是