这个排序真的猛,难怪叫快速排序!
简介
快速排序是一种 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], "未排好序!");}}} 小结
快速排序选择基准数时,尽量范围内随机选择,为了解释方便才使用第一个做基准数
由于用到了递归,一定要判定递归结束条件
