QA精选|快速排序中关于小于与小于等于的问题

Posted 九章算法

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QA精选|快速排序中关于小于与小于等于的问题相关的知识,希望对你有一定的参考价值。

首先声明,因为快排有很多实现方式,这里所说的是我们九章官方提供的快排模板:http://www.jiuzhang.com/solutions/quick-sort

有很多同学可能会问

  1. 为什么这里是A[left] < pivot 而不是 A[left] <= pivot ?
    因为如果pivot刚好是最大值,那么我们对n个元素进行partition就会出现左边得到n个,右边得到0个元素的情况,这样左边继续递归下去有可能始终都是n(每次取出pivot都是最大值),那么会出现无限递归。

  2. 为什么这里是A[right] > pivot 而不是 A[right] >= pivot ?
    同理,因为如果pivot刚好是最小值,那么我们对n个元素进行partition就会出现左边得到0个,右边得到n个元素的情况,这样右边继续递归下去有可能始终都是n(每次取出pivot都是最小值),那么会出现无限递归。

当同学们做到课后作业:
http://www.lintcode.com/en/problem/sort-colors-ii/的时候,根据我们提供的官方题解:http://www.jiuzhang.com/solution/sort-colors-ii/
大家可能会产生新的疑惑:
这里 while (l <= r && colors[l] <= colorMid)
对于这个while循环为什么是<= 不是 < , 它为什么和快排不一样呢 ?
首先由如下几个地方大家需要注意:

  1. 因为rainbowSort的递归里 (..., colorMid + 1, colorTo),colorMid的值不能混到右边去,因为右边值的区间是[colorMid + 1, colorTo], 左边的值是[colorFrom, colorMid],所以我们需要把等于colorMid的值放在partition的左侧,而不是像快排一样,等于pivot的值的元素放在左侧或者右侧是无所谓的。这里我们应该分别使用colors[l] <= colorMidcolor[r] > colorMid

  2. 因为在条件colorFrom >= colorTo的时候我们已经return了,所以求colorMid的时候,colorFrom一定不等于colorTo。又因为colorMid = (colorFrom + colorTo) / 2, 所以colorMid一定不会等于最大值colorTo,也就避免了我们所说的因为pivot是最大值而导致无限递归的问题,所以我们可以放心的使用<=

综上两个原因,导致了ranbowSort算法里面和快排略有不同的原因。

对于这个问题更多的讨论,请看原帖:https://www.jiuzhang.com/qa/4289/ 或点击原文链接。



九章算法 | 帮助更多中国人找到好工作


《OOD面向对象专题班》

《系统设计班》

《Java入门与基础算法班》

《九章算法班》


正在报名中!

报名登陆官网 www.jiuzhang.com

或点击文末“阅读原文”

以上是关于QA精选|快速排序中关于小于与小于等于的问题的主要内容,如果未能解决你的问题,请参考以下文章

随机快速排序的细节和复杂度分析

算法 - 快速排序 - 经典快排 | 随机快排

排序算法积累-----快速排序

快速排序与归并排序

快速排序的错误

快速排序 + 代码实现(C语言)