数据结构与算法之七(划分算法与快速排序)

旁白:开始之前先回答一下上一节的问题,排序算法为什么要讨论是否稳定?也就是说相同关键字元素在前在后有什么区别吗?

网上有人举了一个栗子:假如发奖学金,排在前三个的有奖,结果一排序把原来在第三位的并列第三名给弄到第四位了,他估计不会乐意。

分析:实际上这个栗子不太准确,因为问题的产生是由于现实的需要,现实中估计需要并列第三名才能解决问题。也就是现实中存在这样的矛盾,有些时候的问题只能稳定排序来解决。

实际上现实中有这样的问题,上面的栗子改一改,比如学校奖学金名额有限,3等奖有20个,困难生优先,而学校这次符合的人数有21个,名单上是按困难程度排序的(先决条件是2号关键字有序),这时候只要按成绩排个序(1号关键字无序),这时候就希望成绩相同的时候维持原有的困难程度,位序不要发生变化,你该选择哪种排序呢?

好了进入今天的正题

快速排序

有一个哥们已经总结的很好了,不造轮子了,大家先看看这篇,讲的很清楚http://www.cnblogs.com/orlion/p/5350891.html

总结:
1)快速排序做了3件事情:

quickSort(array, left,right){
//a.选择中间数
    int middleNum = getMiddleNum(array);
//b.划分,把序列分成大于中间数的部分和小于中间数的部分
    int middleIndex = divide(array, left,right);
//c.递归,分别对两部分进行快速排序
    quickSort(array,0,middleIndex);
    quickSort(array,middleIndex+1,right)
}

2)中间数的选择不必纠结,个人觉得好点可以随机采样求均值,选出的中间数不在序列中。而“三数据项取中值”的做法选出的中间数存在序列中,可以对算法微微进行优化,在选出中值的同时,首中尾元素已经排序,可以不再参与划分。

3)那篇文章中划分算法交换两个元素用的是异或^, A^B^B=A

4) 由于划分算法的缘故,快速排序也是不稳定的。比如5,3,3。选择middleNum=4,这时候left停在5的位置,right停在末尾3的位置,交换首尾,两个3的相对位置发生了变化。

5)快排的复杂度,划分的过程跟二分类似,复杂度为N*logN。

扫描二维码关注公众号,回复: 4973543 查看本文章

快速排序的优化

其实对于最小粒度的划分,比如3个元素,用划分并不划算,如果是用三数据项取中值,也不用进入划分,排完序就结束了。这种最小粒度的直接排序即可。对于小粒度的划分,比如10个元素,可以用插入排序。

那么问题来了,快速排序用了递归,能否非递归实现?

猜你喜欢

转载自blog.csdn.net/kkae8643150/article/details/78401968