关于快速排序的左右优先方向问题

正确代码

正确代码是这样的
(升序进行说明)

    public static void quickSort(int[] array, int left, int right){
        //递归结束条件
        if(left > right) {
            return;
        }
        //左端基准值
        int base = array[left];
        int i = left, j = right;
        while(i != j) {
        	//从右端开始查找
            while(array[j] >= base && i < j) {
                j--;
            }
            //从左端开始查找
            while(array[i] <= base && i < j) {
                i++;
            }
            //若是因为找到符合调换条件的值就调换
            if(i < j) {
                int tmp = array[i];
                array[i] = array[j];
                array[j] = tmp;
            }
        }
        array[left] = array[i];
        array[i] = base;
        quickSort(array, left, i - 1);
        quickSort(array, i + 1, right);
    }

问题

那么为什么把

 //从右端开始查找
while(array[j] >= base && i < j) {
    j--;
 }
 //从左端开始查找
while(array[i] <= base && i < j) {
     i++;
}

改成:

 //从左端开始查找
while(array[i] <= base && i < j) {
     i++;
}
 //从右端开始查找
while(array[j] >= base && i < j) {
    j--;
}

就不对?

原因

实际上跟我们的

//左端基准值
int base = array[left];

有关。

应该是这样的:

左端基准值要从右边开始查找
右端基准值要从左边开始查找

原因(升序和左基准为例):
在快排时,当两头的索引遇见时,相遇点对应的值就会和基准点进行数据交换。我们要知道:
在进行基准点数据交换后要满足两个条件:

  • 相遇点左边都要比基准值小
  • 相遇点右边都要比基准值大

若从左边先开始,那么左端停止的值一定是比基准值大的值或整体停止值,若停止值也同样是比基准大的值,那么该值不会被交换到右边,只会和基准值进行交换,所以就被放在了左边,进行下一轮新的排序,并且永远不会参与进相遇值右边的排序中,就导致了一些较大的值存在了左边。
举个例子:

例子	: 7	3	2	8	9

像这样:基准值:7 。若左边开始就会停止在8的位置,右边以i==j被迫停止,7和8交换,造成

一次排序结果:	8	3	2	7	9

在进行下一次递归时:8 3 2 被分成新的快排组合,9自己被分成快排组合
那么从此 8 就走向了不归路

若是从右边开始相遇值必须停止或者是比基准值小的值,当该值是小于基准值同时为相遇值就会和基准值交换,此时该值刚好是比基准值小的值,所以符合。
右边开始从根本上避免了:左边遇见比基准值大的值,右边却无与此值交换的值

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

「 25' h 」

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值