一篇看懂快速排序QuickSort算法与代码

本文介绍了快速排序算法的原理,通过代码实例演示了其工作流程,特别关注了其性能分析,包括时间复杂度和空间复杂度,并指出快速排序是非稳定排序。讨论了在特定场景下代码实现的细节,如基准值选择对效率的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原理

快速排序(Quicksort)是对冒泡排序的一种改进,由东尼·霍尔在1960年提出。
快速排序是指通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序。整个排序过程可以递归进行,以此达到整个数据变成有序序列。快速排序不是稳定的排序算法。
在这里插入图片描述

快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。
步骤为:

  1. 从数列中挑出一个元素,称为“基准值”(pivot)。
  2. 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  3. 递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。
  4. 递归到最底部时,数列的大小是小于1,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
    在这里插入图片描述

代码实现

    public static void quickSort(int[] array) {
        QuickSortRange(array, 0, array.length - 1);
    }

    private static void QuickSortRange(int[] array, int from, int to) {

        int size = to - from + 1;

        if (size <= 1) {
            return;
        }

        int pivotIdx = partition(array, from, to);

        QuickSortRange(array, from, pivotIdx - 1);
        QuickSortRange(array, pivotIdx + 1, to);
    }

    private static int partition(int[] array, int from, int to) {

        int pivot = array[from];//基准值

        int left = from;
        int right = to;

        while (left < right) {

            while (left < right && array[right] >= pivot) {
                right--;
            }
            while (left < right && array[left] <= pivot) {
                left++;
            }

            int tmp = array[left];
            array[left] = array[right];
            array[right] = tmp;
        }

        int tmp = array[from];
        array[from] = array[left];
        array[left] = tmp;

        return left;
    }

代码分析

在这里插入图片描述

在这里插入图片描述
补充:
partition方法内:基准值是传入区间最左边元素,所以方法的内循环先从右边开始。
如果先走左边,对一个有序的数组排序时,left走第一步就遇到大于基准值的内容,第一个内循环终止。left停下,然后右边right一直在走, 走到left此时的位置时停下来,left>=right,while外循环循环结束,此时left为第二个元素,为第二小的数,基准值为第一个元素,为第一小的数;然后交换基准值与left下标的值,交换以后反而第一个元素和第二个元素出现问题(逆序)。所以不能先走左边。
例如:
需要快速排序的是int[] array = {1,2,3,4,5};
在这里插入图片描述

性能分析

在这里插入图片描述
时间复杂度:
因为快速排序一直在利用基准值将区间递归分为左右两个小区间,图解像一个二叉树,所以二叉树的深度可以形象的比作快速排序要执行的次数。当固定的区间长度为完全二叉树时,深度最低,时间复杂度最小,为O(log(n));当固定的区间长度为单支二叉树时,深度最高,时间复杂度最大,为O(n)。

空间复杂度:
快速排序和归并排序是七大排序中唯二的空间复杂度不是O(1)的排序算法。

稳定性

快速排序不是稳定的排序算法。
如果left与基准值交换之前,最后的left停下的值和基准值相等,之后一交换,同等大小的元素,前面的交换到了后面,后面的交换去了前面。
例如:int[] array = {8,5,4,8,9,9,10};
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值