QA精选|快速排序中关于小于与小于等于的问题
Posted 九章算法
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QA精选|快速排序中关于小于与小于等于的问题相关的知识,希望对你有一定的参考价值。
首先声明,因为快排有很多实现方式,这里所说的是我们九章官方提供的快排模板:http://www.jiuzhang.com/solutions/quick-sort
有很多同学可能会问
为什么这里是A[left] < pivot 而不是 A[left] <= pivot ?
因为如果pivot刚好是最大值,那么我们对n个元素进行partition就会出现左边得到n个,右边得到0个元素的情况,这样左边继续递归下去有可能始终都是n(每次取出pivot都是最大值),那么会出现无限递归。为什么这里是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循环为什么是<=
不是 <
, 它为什么和快排不一样呢 ?
首先由如下几个地方大家需要注意:
因为rainbowSort的递归里
(..., colorMid + 1, colorTo)
,colorMid的值不能混到右边去,因为右边值的区间是[colorMid + 1, colorTo], 左边的值是[colorFrom, colorMid],所以我们需要把等于colorMid的值放在partition的左侧,而不是像快排一样,等于pivot的值的元素放在左侧或者右侧是无所谓的。这里我们应该分别使用colors[l] <= colorMid
和color[r] > colorMid
因为在条件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精选|快速排序中关于小于与小于等于的问题的主要内容,如果未能解决你的问题,请参考以下文章