快速排序
普通快速排序在多数值==v的情况下,表现不佳。原因在于part左右分配不均,引发退化。优化后,会将==v部分part左右平分,消除影响,但仍然不是最佳之选。
/**
* 快速排序优化
*/
public class QuickSortFast {
public static void sort(Integer[] arr){
Integer n = arr.length;
quickSort(arr,0,n-1);
}
private static void quickSort(Integer[] arr, int l, int r) {
if(r-l<=15){
InsertionSort.sort2(arr,l,r);
return;
}
int p = partition(arr,l,r);
quickSort(arr,l,p-1);
quickSort(arr,p+1,r);
}
// 返回p,使得arr[l...p-1]<arr[p]; arr[p+1...r]>arr[p]
private static int partition(Integer[] arr, int l, int r) {
// 随机选取标定元素
Tlt.exch(arr,l,StdRandom.uniform(l, r));
Integer v = arr[l];
// arr[l+1...i) <= v; arr[j...r] >= v
int i = l+1,j = r;
while(true){
while(i <=r && arr[i]<v) i++;
while(j >= l+1 && arr[j]>v) j--;
if(i>j)break;
Tlt.exch(arr,i,j);// 这种情况在arr[i]=v=arr[j]的情况下也会交换。但是好在将等于v的数据在part两部分平分了,阻止退化成on^2。
i++;
j--;
}
Tlt.exch(arr,l,j);
return j;
}
public static void main(String[] args) {
Integer[] random = Tlt.random(100000, 0, 100000);
sort(random);
Tlt.show(random);
}
}
三路快速排序实现
/**
* 三路快速排序
*/
public class QuickSort3Ways {
public static void sort(Integer[] arr){
Integer n = arr.length;
quickSort3Ways(arr,0,n-1);
}
private static void quickSort3Ways(Integer[] arr, int l, int r) {
if(r-l<=15){
InsertionSort.sort2(arr,l,r);
return;
}
Tlt.exch(arr,l,StdRandom.uniform(l, r));
Integer v = arr[l];
int lt= l; // arr[l+1...lt] < v
int gt = r+1; // arr[gt...r] > v
int i = l+1; // arr[lt+1...i] == v
while(i<gt){
if(arr[i] < v){
Tlt.exch(arr,i,lt+1);
lt++;
i++;
}else if(arr[i]>v){
Tlt.exch(arr,i,gt-1);
gt--;
}else{
i++;
}
}
Tlt.exch(arr,l,lt);
quickSort3Ways(arr,l,lt-1);//不考虑==v部分
quickSort3Ways(arr,gt,r);//不考虑==v部分
}
public static void main(String[] args) {
Integer[] random = Tlt.random(100000, 0, 100000);
sort(random);
Tlt.show(random);
}
}
void quickSort3Ways(Integer[] arr, int l, int r)
三路排序将数组分成三个部分 >v,==v,等于v。遍历元素
当e==v
当e<v
当e>v
交换之后,i虽然不需要变大,但是gt需要减1维护>v的结构
初始化
当i==gt的时候遍历结束
交换标准元素v