普通快排,最差情况下为时间复杂度O(N^2)
随机快排,最差情况下为时间复杂度O(N*logN),最好空间复杂度O(logN),最差O(N)
原始快排:将数组最后一个变量假设为X,小于等于X的放左边,大于X的放右边,然后再将拍好序的左边和右边分别再重复刚刚的动作
改进快排:将数组最后一个变量假设为X,小于X的放左边,等于X的放中间,大于X的放右边,这样的好处是中间排好序的X不用动
public static void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {//空或长度小于2个,不用排序
return;
}
quickSort(arr, 0, arr.length - 1);
}
//随机快排,随机取一个数,让它和数组的最后一位交换,然后按最后一位进行普通快排
public static void quickSort(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);//以数组最后一个作为比较的数,小于放左边,等于放中间,大于放右边,和荷兰国旗问题一样,只不过多了递归
quickSort(arr, l, p[0] - 1);//递归左边,不包括等于的数字
quickSort(arr, p[1] + 1, r);//递归右边,不包括等于的数字
}
}
public static int[] partition(int[] arr, int l, int r) {
int less = l - 1;
int more = r;
while (l < more) {
if (arr[l] < arr[r]) {
swap(arr, ++less, l++);
} else if (arr[l] > arr[r]) {
swap(arr, --more, l);
} else {
l++;
}
}
swap(arr, more, r);//默认最后一个数不参与排序,等排完和大于区域的第一个数交换
return new int[] { less + 1, more };
}
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}