目录
前言
当我在手撸快排代码的时候,我当时是先从前往后进行寻找,找到比基准大的数,然后才从后往前找比基准小的数,但是运行完成之后,我发现排序错误。
于是我发现如果你把第一个作为基准进行快排,然后接着对左半边和右半边分别快排的话,必须先从后往前进行
下面我分别给出这两种顺序得到的快速排序过程和结果
①先从后往前进行
代码:
这段是正确的代码,得到的过程和结果如下:
分析:
我们可以很清楚的看到,每一轮,对于基准的归位,都可以很准确的插入到一个特殊的位置——左边都比他小,右边都比他大,符合我们所认知的快排规律。
以上标红框表示分割,绿框表示已经排好的,橙色框表示左分区待排序列,蓝色框表示右分区待排序列
②先从前往后
代码:
就是刚才两个内部while交换下顺序,直接看过程和结果就行
过程和结果:
(红框是分界线,橙色框表示左分区,蓝色框表示右分区)
我们直接看
第一轮就可以直接看出来了:这个比基数大的13,一直被往右挪,并且后面一直被交换,直到两边start和end重合,最终导致了一个结果:
得到的左分区并不是全都小于原来的基准5:
这个是致命的错误,违反了快速排序的规律,最后得到的也确实是个错误的结果:
其实还有个极端例子:
[2,5]你采用先从前往后,从1索引开始,第一次直接跳出了,然后做了交换(基准索引0和start,end指向的索引1交换),最后[5,2]显然是错的
结论:
在我们进行标准的快速排序的时候(以第一个索引作为基准),必须先从后往前找,然后再从前往后找。否则会出现:交换完之后,左分区并不是全部小于基准的情况
因为如果每次都从左边的start先开始,最终两边的start和end 相遇的索引位置 对应的元素值 是大于基准的。