快速排序

什么是快速排序

个人认为,本质上就是“冒泡”的高级版。

它的原则是:

  1. 从排序的数列中,选一个数作为“基准数”,个人更喜欢叫它“基数”
  2. 根据选定的“基数”,分为 2 部分。比“基数”大的放一边,比“基数”小的放到另一边。
  3. 分别对 2 部分数列,重复步骤 1、2。直到队列中只有一位数时。

代码说话


    public void sort(int left, int right, int... sortNums) {
        if (left >= right) {
            return;
        }

        // 确定“基”数为左边的第一个
        int flag = sortNums[left];
        // 确定最左边和最右边的索引,当做探测哨兵。
        int probeLeft = left;
        int probeRight = right;

        // 根据“基”数,分为 2 部分,左边的是比它小的,右边时比它大的。
        // 直到哨兵相遇,才退出循环
        while (probeLeft < probeRight) {
            // 右哨兵先行动,顺序不可乱。

            // 在未和左哨兵相遇,且探测到某数值比“基数”小【之前】,往左哨兵方向一直探索。否则停止行动,等待左哨兵行动
            // 即暂停的情况为:①两个哨兵相遇。②右哨兵探测发现的数值比“基数”小。
            // 往前探测的情况为:两个哨兵未相遇,且右哨兵探测发现的数值比“基数”大。
            while (probeLeft < probeRight && sortNums[probeRight] >= flag) {
                // 右哨兵,往左哨兵地盘行动
                probeRight--;
            }

            // 左哨兵等待行为原则和右哨兵是恰恰相反的。
            while (probeLeft < probeRight && sortNums[probeLeft] <= flag) {
                // 左哨兵,往右哨兵地盘行动
                probeLeft++;
            }

            // 当左右哨兵未相遇,交换左右哨兵探测到的数位置。
            // 左哨兵探测值是比“基数”大。右哨兵探测值是比“基数”小。
            if (probeLeft < probeRight) {
                int temp = sortNums[probeLeft];
                sortNums[probeLeft] = sortNums[probeRight];
                sortNums[probeRight] = temp;
            }
        }

        // 因为是根据“基数”分为2部分,所有需要把“基数”放在【划分点】
        sortNums[left] = sortNums[probeLeft];
        sortNums[probeLeft] = flag;

        // 继续处理左边的。
        sort(left, probeLeft - 1, sortNums);
        // 继续处理右边的。
        sort(probeLeft + 1, right, sortNums);
    }

时间复杂度

最坏为

O(N2)

最好为

O(NlogN)

总结

左哨兵和右哨兵,他们职能各不相同。左为探测比“基数”大的,右为探测比“基数”小的。当两哨兵都完成了当前探测任务时,互换探测到的数值位置。继续进行下一回合探测。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值