![Python算法设计与分析从入门到精通](https://wfqqreader-1252317822.image.myqcloud.com/cover/845/44509845/b_44509845.jpg)
4.6 快速排序算法
快速排序法又称为分割交换法,是对冒泡排序法的一种改进。其基本思想是:先在数据中找一个虚拟的中间值,并按此中间值将打算排序的数据分为两部分。其中,小于中间值的数据放在左边,大于中间值的数据放在右边;再用同样的方式处理左右两边的数据,直到排序完成为止。
例如,有n项数据,数据值用K1, K2, …, Kn来表示。其快速排序法操作步骤如下:
(1)先在数据中假设一个虚拟中间值K(为了方便,一般取第一个位置上的数)。
(2)从左向右查找数据Ki,使得Ki>K,Ki的位置数记为i。
(3)从右向左查找数据Kj,使得Kj<K,Kj的位置数记为j。
(4)若i<j,数据Ki与Kj交换,并回到步骤(2)。
(5)若i≥j,数据K与Kj交换,并以j为基准点分割成左右两部分,然后针对左右两部分再进行步骤(1)~步骤(5),直到左半边数据等于右半边数据为止。
例如,有这样一组数据:6, 1, 2, 7, 9, 3, 4, 5, 10, 8,如图4.41所示。采用快速排序法递增排序,步骤如下。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P107_10189.jpg?sign=1738897014-1MNMcuTXHMbYpIDwPY5jkPXYFuo7PZgg-0-08a53a6e7d13d41eec30835b624dabbc)
图4.41 原始数列
(1)取原始数列的第一个数6为虚拟中间值,即K=6;然后从左向右查找大于6的数,得到数字7,位置i=4;再从右向左查找小于6的数,得到数字5,位置j=8,如图4.42所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P107_10193.jpg?sign=1738897014-HbFkBRpsBtnFJ6W2QwPbbj05gBHKkBLF-0-1753737d75ef0510261f3c01da1ebf7d)
图4.42 步骤(1)排序过程
(2)i<j,因此交换Ki(数字7)和Kj(数字5)的位置,完成第一次排序。继续从左向右查找值大于6的数,即数字9,位置i=5;再从右向左查找值小于6的数,即数字4,位置j=7,如图4.43所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P108_10202.jpg?sign=1738897014-rqm1gESAbcGuRb7pK39IocckVVwIFCYW-0-72be7d029a5d65a08c886038b2dcac68)
图4.43 步骤(2)排序过程
(3)i<j,因此交换Ki(数字9)和Kj(数字4)的位置,完成第二次排序。继续从左向右查找值大于6的数,即数字9,位置i=7;再从右向左查找值小于6的数,即数字3,位置j=6,如图4.44所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P108_10206.jpg?sign=1738897014-5dJlmfqw1QSrX4MJuhKenNwP4bHzs8Mu-0-41849751efa0a9ce8ebd7f09de05943a)
图4.44 步骤(3)排序过程
(4)i>j,因此交换虚拟中间值K(数字6)和Kj(数字3)的位置,完成第三次排序。此时,发现6的左半边都是小于6的数,右半边都是大于6的数,虚拟中间值6变成了真正的中间值,如图4.45所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P108_10210.jpg?sign=1738897014-Wz3MbJiXzeTYVcOCECq1jI6HIpT7I7ij-0-caf7fde010fcc2ad64690ab4b45566b4)
图4.45 步骤(4)排序过程
(5)对中间值6左半边的数据排序,中间值和右半边数据暂时可以忽略。在左半边取第一个位置的数为虚拟中间值,即K=3,从左向右查找大于3的值,即数字5,位置i=4;再从右向左查找小于3的值,即数字2,位置j=3,如图4.46所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P108_10214.jpg?sign=1738897014-MmbWDi1LAwLP0m2mSBGMKYyrs5WlD3mn-0-6fdb5367f3aa2c33e1ebd01ce9934ee7)
图4.46 步骤(5)排序过程
(6)i >j,因此需要交换虚拟中间值K(数字3)和Kj(数字2)的值,如图4.47所示。此时虚拟中间值变成了真正的中间值。小于3的都在中间值3的左半边,大于3的都在中间值3的右半边。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P109_10223.jpg?sign=1738897014-2ld9vbm5e0AdDGolcla5g1DGzobZKLBk-0-93b72afc28f06f663a5b59c243604d24)
图4.47 步骤(6)排序过程
(7)接下来对中间值3的左、右两侧排序,排序后的结果如图4.48所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P109_10227.jpg?sign=1738897014-c6ln6Y44qOdMXdTz8lF6tFfChqeCZM4g-0-f5ac425fff709e1c96eacb767d63b426)
图4.48 步骤(7)排序过程
(8)此时,整组数据的左半边已经完成排序,接下来需要忽略已排序好的左半边和中间值6,对右半边进行排序。取右半边第一个位置的数为虚拟中间值,即K=9,然后从左向右找大于9的值,即数字10,位置i=9;再从右向左找小于9的值,即数字8,位置j=10,如图4.49所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P109_10231.jpg?sign=1738897014-LCMZW8NgRoAxpEsXjgohBu0lOi07tqx7-0-c950edf0d7d1444443458f8393116abb)
图4.49 步骤(8)排序过程
(9)i<j,因此交换Ki(数字10)和Kj(数字8)。然后再从左向右查找大于9的值,即为数字10,位置i=10;再从右向左找小于9的值,即为数字8,位置j=9,如图4.50所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P109_10235.jpg?sign=1738897014-bCpUpE2mEdGR4EBZDmwzgDdznG1c9zSL-0-7f4081e66b5d68eac4ea85cae70d84da)
图4.50 步骤(9)排序过程
(10)i>j,因此交换虚拟中间值K(数字9)和Kj(数字8)的值,此时,虚拟中间值变成为真正的中间值,如图4.51所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P109_10239.jpg?sign=1738897014-58BOSvA3SMpEQzWuRvpjP7fSOuvSsJXW-0-18fd8a86682b2e1d407cb06c4d26af5f)
图4.51 步骤(10)排序过程
(11)以中间值9为界,分为左右两侧,再进行排序,最后完成右半边排序,如图4.52所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P110_10248.jpg?sign=1738897014-ot241P5Dv0z7TW36TIxDDCeO7BkPRRc7-0-3b26c66a4d0b4ca6b1347d890de0887f)
图4.52 步骤(11)排序过程
(12)结合左半边排序和右半边排序,最终的排序结果如图4.53所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P110_10252.jpg?sign=1738897014-dGp0mhC4dtwcmDQTDxiIqDQWr6L0VRwz-0-4a5379cf98d0ece7ed5f7f7d0fe73168)
图4.53 最终排序结果
【实例4.11】 使用快速排序法将列表中的数字递增排序。(实例位置:资源包\Code\04\11)
用Python代码实现上方示例中的快速排序算法,具体代码如下:
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P110_32969.jpg?sign=1738897014-PtRC8ixePLSaBdl9uX3HCZQ1jcesCsUV-0-5cb108946d1a3d2f7bd8bb324d04e767)
运行结果如图4.54所示。
【实例4.12】 入职年限排名。(实例位置:资源包\Code\04\12)
例如,某公司的6名职员入职年限分别是1、3、15、20、5、4。利用快速排序法给这些职员入职年限从高到低顺序排序,用Python实现具体代码如下:
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P111_32970.jpg?sign=1738897014-20VtLl9ehsrWUbImtqAphbZfwKyNBGMd-0-107278a390899f0e59b4c1dbcf49d44d)
运行结果如图4.55所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P111_10594.jpg?sign=1738897014-vvL9VMfsBlKOXsMSKXt3pui81YStIgtQ-0-48d707c827b47c29be3741f39b1a6cde)
图4.54 快速排序法
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P111_10602.jpg?sign=1738897014-6WV4QSqsDy4PT80v8ShzSu9eREBVX8lU-0-93f390c4ea12745bed574113d4163972)
图4.55 运行结果