十大排序--快速排序

快速排序

介绍

快速排序的最坏运行情况是 O ( n ² ) O(n²) O(n²),比如说顺序数列的快排。它的平均期望时间是 O ( n l o g n ) O(nlogn) O(nlogn),对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。

步骤

  1. 从数列中挑出一个元素,称为 “基准”(pivot);
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

演示

推荐排序算法动态调试、演示网站: https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html
图片来源于:https://zhuanlan.zhihu.com/p/93129029,为一次快排的过程

在这里插入图片描述

代码与思想

/**
 * TODO 快速排序
 * 思想:递归,双指针
 *
 * @author nanfeng
 * @date 2022/03/28/ 14:29
 */
public class QuickSort {
    public static void main(String[] args) {
        int[] nums = new int[]{711,42,333,6,7555,85,93,24,30,177};
//        有两个相等的值的情况
//        int[] nums = new int[]{711,42,333,6,7555,85,85,24,30,177};
        // 左、右指针为左闭右闭
        quickSort(nums, 0, nums.length-1);
        System.out.println(Arrays.toString(nums));
    }

    static void quickSort(int[] nums,int left, int right) {
        // 递归的结束条件 左指针大于右指针:
        if(left > right) return;
        // 保留左右指针位置
        int start = left, end = right;
        // 选择一个基准(比较值),快排每一次递归可以确定一个基准的位置,默认采取左指针的值,循环内先遍历右侧,反之同理
        int pivot = nums[left];
        // 循环结束条件:左右指针相等时,说明确定了基准的位置
        while (start != end) {
            // 循环结束条件依然保证左右指针相同(因为循环内 右指针变化),同时保证基准的右侧全是大于其的值

            // 这里有一个注意点
            // 当待排序数组有重复值时,应在左侧或右侧任意一侧处理相等值
            while (end > start && nums[end] >= pivot) end--;
            // 此时右指针指向的值小于基准,将其赋值到左指针处(因为此时左指针的值是大于基准的数)
            nums[start] = nums[end];
            // 同理
            while (start < end && nums[start] < pivot) start++;
            // 此时左指针指向的值大于基准,将其赋值到右指针处(因为此时右指针的值是小于基准的数)
            nums[end] = nums[start];
        }
        // 经过一次递归(一次快排) 确定一个基准值的最终位置,此时左右指针指向同一个位置
        nums[start] = pivot;
        // 小于基准值元素的子数列 进行一次快排
        quickSort(nums, left, start-1);
        // 大于基准值元素的子数列 进行一次快排
        quickSort(nums, start + 1, right);
    }
}

参考:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nan feng

打赏一杯咖啡吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值