当大量出现重复值时,我们使用三路快排,代码如下:
/*
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;
}