當大量出現重復值時,我們使用三路快排,代碼如下:
/*
arr:表示排序數組
l:表示數組左邊界
r:表示數組右邊界
*/
public static void quickSortInternal3(int[] arr,int l,int r) { if(l >= r) return; //隨機取l-r之間的數
int randIndex = (int)(Math.random() * (r - l + 1) + l); //主要還是以首元素作為基准值,只不過該基准值是每次隨機取的,然后將隨機所取的值與首元素交換 //交換l與randIndex
swap(arr,l,randIndex); //基准值為首元素
int v = arr[l]; //arr[l+1.....lt] < v //lt所處的位置就是arr[i]<v的最大邊界
int lt = l; //arr[gt....r] > v //gt所處的位置就是末尾元素
int gt = r + 1; //i用來遍歷數組,
int i = l + 1; while(i<gt) { if(arr[i] < v) { //交換兩者值,lt和i都自增1
swap(arr,lt+1,i); lt++; i++; }else if(arr[i] > v) { //交換兩者值,gt自減1
swap(arr,gt-1,i); gt--; }else { //等於i自增
i++; } } //交換l與lt元素,可以確定基准值的位置
swap(arr,l,lt); //基准值前面繼續進行上述操作
quickSortInternal3(arr, l, lt-1); //基准值后面數組繼續進行上述操作
quickSortInternal3(arr, gt, r); } //交換對應下標數組元素
public static void swap(int[] arr,int i,int j) { int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; }