快排其实没那么快
2014-01-06 20:13
148 查看
考虑快排的过程:随机选择一个元素做“轴元素”,将所有大于轴元素的移到左边,其余移到右边。根据这个过程,快排的第一次比较就是将一个元素和轴元素比较,这个时候显而易见的是,“大于”和“小于”的可能性各占一半。这是一次漂亮的比较。
然而,快排的第二次比较就不那么高明了:我们不妨令轴元素为pivot,第一次比较结果是a1<pivot,那么可以证明第二次比较a2也小于pivot的可能性是2/3!这容易证明:如果a2>pivot的话,那么a1,a2,pivot这三个元素之间的关系就完全确定了——a1<pivot<a2,剩下来的元素排列的可能性我们不妨记为P(不需要具体算出来)。而如果a2<pivot呢?那么a1和a2的关系就仍然是不确定的,也就是说,这个分支里面含有两种情况:a1<a2<pivot,以及a2<a1<pivot。对于其中任一种情况,剩下的元素排列的可能性都是P,于是这个分支里面剩下的排列可能性就是2P。所以当a2<pivot的时候,还剩下2/3的可能性需要排查。
再进一步,如果第二步比较果真发现a2<pivot的话,第三步比较就更不妙了,模仿上面的推理,a3<pivot的概率将会是3/4!
这就是快排也不那么快的原因,因为它也没有做到每次比较都能将剩下的可能性砍掉一半。
然而,快排的第二次比较就不那么高明了:我们不妨令轴元素为pivot,第一次比较结果是a1<pivot,那么可以证明第二次比较a2也小于pivot的可能性是2/3!这容易证明:如果a2>pivot的话,那么a1,a2,pivot这三个元素之间的关系就完全确定了——a1<pivot<a2,剩下来的元素排列的可能性我们不妨记为P(不需要具体算出来)。而如果a2<pivot呢?那么a1和a2的关系就仍然是不确定的,也就是说,这个分支里面含有两种情况:a1<a2<pivot,以及a2<a1<pivot。对于其中任一种情况,剩下的元素排列的可能性都是P,于是这个分支里面剩下的排列可能性就是2P。所以当a2<pivot的时候,还剩下2/3的可能性需要排查。
再进一步,如果第二步比较果真发现a2<pivot的话,第三步比较就更不妙了,模仿上面的推理,a3<pivot的概率将会是3/4!
这就是快排也不那么快的原因,因为它也没有做到每次比较都能将剩下的可能性砍掉一半。
相关文章推荐
- 【漫画】谷歌眼镜Google Glass其实不是那么受欢迎!
- 简单点儿、简单点儿、再简单点儿,其实世界可以不是我们想象的那么复杂
- [冲刺攻略] 公考其实没有你想象的那么难!(行测80分高手独家经验分享)
- 其实都是那么平凡
- 委托其实不是那么苦涩难懂
- [外包速递] 开发者其实就差那么一点——让CSDN放大你的成长!
- 其实,异常并不是那么难理解。——你不知道的异常(一)
- 其实“指针”也没那么困难
- ArrayList其实就那么一回事儿之源码浅析
- [外包速递] 开发者其实就差那么一点——让CSDN放大你的成长!
- HashMap其实就那么一回事儿之源码浅析
- <编程珠玑>向量旋转(旋转交换) 第三种方法实现代码, 杂耍,其实也没那么容易出错.
- 要知道其实自己并没有那么出众,你若盛开,清风自来!(低要求,高行动)
- 从Follower变成Leader,其实没你想象那么难
- 放纵的感觉其实没有想象的那么好!
- 技术的贡献率其实并没有你原来想象的那么高
- tnsnames.ora其实没有什么用,只是供plsql等工具,进行便捷访问的,那么怎么知道plsql读取的是哪个tnsnames.ora文件配置?
- 手机其实没有你想象得那么安全!
- 其实自己喜欢说的话就是那么几句,不信你看看