前言
三路快速排序主要可以对具有重复元素的数组进行优化,
在partition的过程中将重复元素v均放在区间[lt + 1, i - 1] ,使得arr[lt + 1, i - 1] == v ,递归则从[l, lt - 1],和[gt, r]继续,避开了[lt + 1, i - 1]。
代码
import java.util.Arrays;
import java.util.Random;
public class QuickSort {
private QuickSort(){}
public static <E extends Comparable<E>> void sort3ways(E[] arr){
Random rnd = new Random();
sort3ways(arr, 0, arr.length - 1, rnd);
}
private static <E extends Comparable<E>> void sort3ways(E[] arr, int l, int r, Random rnd){
if(l >= r) return;
/** 三路快速排序的 partition 过程 **/
// 生成 [l, r] 之间的随机索引
int p = l + rnd.nextInt(r - l + 1);
swap(arr, l, p);
// arr[l + 1, lt] < v, arr[lt + 1, i - 1] == v, arr[gt, r] > v
int lt = l, i = l + 1, gt = r + 1;
while(i < gt){
if(arr[i].compareTo(arr[l]) < 0){
lt ++;
swap(arr, i, lt);
i ++;
}
else if(arr[i].compareTo(arr[l]) > 0){
gt --;
swap(arr, i, gt);
}
else{ // arr[i] == v
i ++;
}
}
swap(arr, l, lt);
/** 三路快速排序的 partition 过程结束 **/
// 递归调用
//注意, 这里lt-1是因为上面的swap操作(此时lt位置上的值是v)
sort3ways(arr, l, lt - 1, rnd);
sort3ways(arr, gt, r, rnd);
}
private static <E> void swap(E[] arr, int i, int j){
E t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
}