上一篇学习中介绍了了递归算法在排序中的一个应用:归并排序,在排序算法中还有一种算法用到了递归,那就是快速排序,快速排序也是一种利用了分而治之策略的算法,它由C.A.R发明,它依据中心元素的值,利用一系列递归调用将数据表划分成越来越小的子表。在每一步调用中,经过多次的交换,最终为中心元素找到最终的位置。与归并算法不同,快速排序是就地排序,而归并排序需要把元素在临时向量中拷贝,下面通过对以下向量进行排序来理解和加深快速排序算法的步骤:
v={800,150,300,650,550,500,400,350,450,400,900};
利用快速排序算法对此数据表进行排序的第0级划分过程如下: 向量v的索引范围为:[first,last) = [0,10),则中心点的索引为mid = (0+10)/2=5,中心点的值为v[5] = 500
快速排序算法的第一次划分的目的就是将向量v依据v[5]的值划分成两个子表subList1和subList2,其中subList1中的值都小于v[5],而subList2中的值都大于v[5],我们将subList1称为左子表,subList2称为右子表,并且确定v[5]的最终位置
下面就是实现这一目的需要我们作出的工作步骤:
1)首先将中心元素与起始位置的元素进行交换。
2)分别扫描左子表和右子表,左子表扫描起始位置为 first+1, 右子表从last-1开始。左子表从左向右扫描扫描,右子表从右向左扫描。直到左子表扫描位置大于或者等于右子表扫描位置时候结束。
在第一个步骤中,得到如下的数据表
500 150 300 650 550 800 400 350 450 400

而此时的左子表扫描位置处于索引1处,右子表扫描位置处于索引9处,先从左子表扫描,直到找到数据值大于中间值500的位置停止扫描,然后扫描右子表,直到找到数据值小于中间值500并且右子表的扫描位置(scanDown)要小于左子表开始位置,防止数据溢出。找到之后,交换左子表与右子表中中扫描位置的元素,图示如下:

在交换v[3](650>500)与v[8](450<500)后,继续扫描左子表和右子表,如图

直到满足条件scanUp>=scanDown,然后scanDown所在位置就是中心元素500的最终位置,交换v[0]与v[scanDown)=v[5],第一次划分级别的最终结果数据集为:400,150,300,450,350,500,800,550,650,900,此时得到的左子表为:400,150,300,450,350,右子表为:800,550,650,900










