【基础算法】快速排序

在这里插入图片描述

采用交换法的实现:

// 递归实现
public void digui(int[] a, int left, int right) {
    if (left >= right) return;
    int pivot = left;
    int l = left + 1;
    int r = right;
    // 注意三个地方为 l <= r(而不是 l < r),否则可能会引起错误的元素交换
    while (l <= r) {
        // l <= r 则可以保证不会数组越界
        while (l <= r && a[l] <= a[pivot]) {
            ++l;
        }
        // l <= r 则可以保证不会数组越界
        while (l <= r && a[r] >= a[pivot]) {
            --r;
        }
        // 如果 l == r 则没必要交换
        if (l < r) {
            Common.sweap(a, l, r);
        }
    }
    Common.sweap(a, left, r);
    digui(a, left, r - 1);
    digui(a, r + 1, right);
}

// 迭代实现
public void diedai(int[] a) {
    // 大致跟递归的实现相同,只不过需要一个容器用于存放中间过程中子数组的边界 index
    Queue<int[]> list = new LinkedList<>();
    int[] first = new int[]{0, a.length - 1};
    list.add(first);
    // 然后需要主要的就是在利用容器进行循环操作时
    // 要避免 java.util.ConcurrentModificationException
    while (!list.isEmpty()) {
        int[] tmp = list.poll();
        int p = tmp[0];
        int l = p + 1;
        int r = tmp[1];
        while (l <= r) {
            while (l <= r && a[l] <= a[p]) ++l;
            while (l <= r && a[r] >= a[p]) --r;
            if (l < r) {
                Common.sweap(a, l, r);
            }
        }
        Common.sweap(a, p, r);
        if (p < r - 1) {
            list.add(new int[]{p, r - 1});
        }
        if (r + 1 < tmp[1]) {
            list.add(new int[]{r + 1, tmp[1]});
        }
    }
}

针对于上面的交换法递归实现进行性能分析:

最好的情况为每次划分过程产生的区间大小都为 n/2,则时间复杂度为 O(n log n),其中 n 代表内部循环的时间复杂度(即上面外层的 while 循环,这个是固定的),而对于空间复杂度,递归树的深度为 log2 n,其空间复杂度也就为 O(log n);

最坏的情况则是每次划分过程产生的两个区间分别包含 n-1 个元素和 1 个元素的时候,则时间复杂度为 O(n2),而对于空间复杂度,需要进行n‐1递归调用,其空间复杂度为 O(n);

平均情况:时间复杂度为 O(n log n),空间复杂度为 O(log n)。

具体参考:https://baike.baidu.com/item/快速排序算法/369842?fromtitle=快速排序&fromid=2084344#6_3

对于迭代的实现,本质上也是一样的。

补充:[算法] 关于快速排序的四种写法

快速排序是一种不稳定的排序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值