这个排序真的猛,难怪叫快速排序!
简介
快速排序是一种 O(logn) 时间复杂度的排序,它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。【来自百度百科】
解析
首先给定一个数组 arr = { 5,8,7,3,4,9 },此时需要排序的位置为左边 left = 0 , 右边为 right = 5
选择第一个数为基准数记为 pivot = 5,此时 left = 0
开始从后面找比基准数小的数
right = 5 此时 arr[5] = 9 > pivot 不满足 right--
right = 4 此时 arr[4] = 4 < pivot 满足
然后把 arr[4] 的值填入 arr[left] 也就是 arr[0] 中,此时数组为 4 8 7 3 4 9
开始从前面找比基准数大的数字
left = 0 此时 arr[0] = 5 == pivot 不满足 left++
left = 1 此时 arr[1] = 8 满足
然后把 arr[1] 的值填入 arr[right]也就是 arr[4]中,此时数组为 4 8 7 3 8 9
重复步骤3,right = 3 时,与left = 1 交换得到数组为 4 3 7 4 8 9
重复步骤4,left = 2 时,与right = 3 交换得到数组为 4 3 4 7 8 9
重复步骤3,此时 right = 2 与 left = 2 相同,则说明比较结束,将 pivot放入right的位置,即 arr[2] = 5 数组为 4 3 5 7 8 9
此时pivot左边均比5小,右边均比5大,完成对这个数的排序
接下来递归 [0,right-1]序列和[right-1,arr.length]序列完成所有排序
代码示例
-
package com.wangp.myaop.coding;
import java.util.Arrays;
import java.util.Random;
import org.apache.http.util.Asserts;
/**
* @author tooStrongerW
* @version 1.0
* @date 2021/3/30 21:16
*/
public class QuickSort {
public static void main(String[] args) {
// 指定数组大小
int capacity = 10_000;
// 生成随机数组
int[] arr = genRandomArr(capacity);
// 排序
quickSort(arr);
// 断言数组顺序
checkArrOrder(arr);
}
private static void quickSort(int[] arr) {
quickSort(arr, 0, arr.length - 1);
}
private static void quickSort(int[] arr, int left, int right) {
// 递归退出条件
if (left >= right) {
return;
}
// 选取基准数
int pivot = arr[left];
int start = left;
int end = right;
// 开始比较
while (start < end) {
// 当 start 小于 end 并且后面的值大于或等于基准值的时候,后面指针向前移动
while (start < end && arr[end] >= pivot) {
end--;
}
// 填空
if (start < end) {
arr[start] = arr[end];
}
// 当 start 小于 end 并且前面面的值小于或等于基准值的时候,前面指针向后移动
while (start < end && arr[start] <= pivot) {
start++;
}
// 填空
if (start < end) {
arr[end] = arr[start];
}
// 比较完成,让基准数回到它该到的位置
if (start >= end) {
arr[start] = pivot;
}
}
// 相同方式排序左子序列
quickSort(arr, left, end - 1);
// 相同方式排序右子序列
quickSort(arr, end + 1, right);
}
private static int[] genRandomArr(int capacity) {
int[] arr = new int[capacity];
Random random = new Random();
for (int i = 0; i < capacity; i++) {
int num = random.nextInt(capacity);
arr[i] = num;
}
return arr;
}
private static void checkArrOrder(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
Asserts.check(arr[i] <= arr[i + 1], "未排好序!");
}
}
}
小结
快速排序选择基准数时,尽量范围内随机选择,为了解释方便才使用第一个做基准数
由于用到了递归,一定要判定递归结束条件