快排要从右开始的原因

在《啊哈算法》一书上的例子是从右开始的,还强调了几次必须。其他书籍教程应该也一样

为什么一定要从右边开始呢?

让我们来试试从左边开始会怎样~

还是用了书上的从小到大排序的例子:

不过我们是从 i 向右走开始,前面几步的 i , j 换位没出现什么问题,图片就不放出来了,下面放了张会出现问题的步骤的图。



i[4] 开始向右走,i 希望寻找一个比基准数 6 大的数,i 走到 3 时,不满足,继续走到 9 ,这时找到了要找的数停了下来。

然后 j[9] 准备,因为 ij 的位置重合了, 所以 j 没有动, 所以数字 9 和基准数 6 的位置交换。

原来的61254397108
交换后91254367108
👆👆

按快排规则,基准数归位后

基准数左边的数小于等于基准数(6)
基准数右边的数大于等于基准数(6)

然而,9在最左边,明显左边的数没有都小于等于基准数6,这时就出现了排序错误。

总结

如果从小到大排序的快排从 i 开始向右走,也就是寻找比基准大的数:

while (a[i] <= key && i < j) ++i;
while (a[j] >= key && i < j) --j;

i 停下来时,a[i] 的值大于基准数或走到了尽头。
i 没有走到尽头,也就是说 i 找到了一个大于基准的数,
接着 j 开始向左走,企图寻找一个小于基准的数,但是存在 i < j 这个条件的限制,j 有可能没找到小于基准的数时就被迫停下来了,此时 i == j 的位置与基准数交换位置,结果就会出现错误。

核心逻辑

从小到大排序的话

基准在左边时:

  1. 如果从 i 左侧开始向右寻找大于基准的值,当停下来时,这个位置左边可能存在比基准小的值,但是 j 已经被循环条件卡住了,过不来,导致排序异常。
  2. 如果从 i 右侧开始向左寻找小于基准的值,当停下来时,这个位置右侧可能存在比基准大的值,而这刚好符合“基准数右边的数都大于等于基准数”的逻辑,所以是正确的!

基准在右边时反过来就行。

所以不管基准值在左还是右,只要从它的对面的方向开始寻找,那么算法就是正确的。

只有了解了这个逻辑,疑问就迎刃而解啦!

  • 17
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值