在前两篇文章中介绍了快速排序的两种方法,分别是左右指针法和挖坑法,今天来介绍第三章方法:前后指针法:其基本思想是:
1,首先保存最后一个位置的值作为key值;
2,通过前(prev)后(cur)两个指针来遍历待排序的数组;
3,若当前位置(cur)的值要小于key值,则加加prev并且交换prev和cur处的;若当前位置(cur)的值大于等于则跳过(cur++),当cur访问到最后一个位置时结束;
4,处理完后,prev处及其左边都是比key小的值,其右边都是不小于key的值,再++prev然后和最后位置的基准值交换,这样就可以确保以基准值为中分为左右两个子序列了。
下面通过图解说明:
1:保存key值
2:设定前后指针,通过cur指针遍历:
3:9>=key,跳过,访问1,1<key,所以++prev;然后交换prev和cur处的值:
重复:2<key,所以++prev(只有当访问的值小于key时,prev才++);然后交换prev和cur处的值:
5和7 >= key,跳过(只需cur++),然后访问4时,4<key,所以++prev,再交换:
8和6 >= key,跳过,然后访问3时,3<key,所以++prev,再交换:
cur继续加加,访问到最后,结束。
4:++prev,和基准值进行交换:
经过上述的过程后,该序列就会以prev位置分为左右序列:
然后继续递归上述的过程,最终实现对数组的排序。再接下来递归时,两个序列的begin和end分别是[left,prev-1]和[prev+1,right],因为prev处的值已经到了其该到的位置,所以prev处并不用继续排序,只需对左右子序列进行排序即可。实现代码如下:
为了确保基准值不选到最大或最小,仍然进行"三数取中"的方法来保证。在PartSort3函数中if语句中有++prev != cur才进行交换,这句代码的意思是如果刚开始进来访问的位置处的值就比key小,并且++prev后prev和cur指向同一个位置(例如cur=0,prev=cur-1,当访问0位置处的值比key小,则++prev后等于cur,两个同时指向0位置处),则交换不交换都可,所以不交换也行,当不相等时的交换才有意义。下面注释的代码是进行交换的。
快速排序的实现使用了三种方法,1,左右指针法;2,挖坑法;3,前后指针法;这三种方法实现的效率基本相同,只是思想不同,大家可以根据自己的理解来掌握其中一种。谢谢。