经典快排每次只解决一个数:小于等于这个数放左边,大于的放右边。
而改进的快排选中一个基准数,将数组分为三个区:小于区,等于区,大于区。这就解决了经典快排每次只解决一个数的问题。
public class QuilkSort {
public static void main(String[] args) {
int[] arr = {3,2,1,3,8,7,5,4,3};
quilkSort(arr);
for(int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
public static void quilkSort(int[] arr) {
if(arr == null || arr.length < 2)
return;
quilkSort(arr,0,arr.length-1);
}
public static void quilkSort(int[] arr, int l, int r) {
if(l < r) {
swap(arr, l + (int) (Math.random() * (r - l + 1)), r); //随机快排代码
int[] p = partition(arr, l, r);
quilkSort(arr, l, p[0] - 1);
quilkSort(arr, p[1] + 1, r);
}
}
public static int[] partition(int[] arr, int l, int r) { //默认选数组最后一个数为基准数
int less = l - 1; //小于区下标
int more = r + 1; //大于区下标
int cur = l;
while(cur < more) {
if(arr[cur] < arr[r]) { //小于区向后扩一个位置
swap(arr, ++less, cur++);
}else if(arr[cur] > arr[r]) {
swap(arr, --more, cur); //大于区向前扩一个位置
}else
cur++;
}
return new int[]{ less + 1, more - 1 }; //返回等于值数组下标
}
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
swap(arr, l + (int) (Math.random() * (r - l + 1)), r)加上这句代码变为随机快排,每次从数组中随机选一个数字作为基准数。