![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=1738950715-Otxyy06eLBWHvNVxHd2gbn6jTZTYPv9r-0-bca7fa173e688a767ac0a45fdc90c554)
图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=1738950715-WsMx8iGjuAu9c4zIvNwc2fgvmMrp5VGt-0-9e32063f2467d558f8497b9e62e54981)
图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=1738950715-wiUvQ2t7UlY4k7nNW7j4dLgU56Y5If4w-0-57a7bede08f160304f093e0d2be6cad9)
图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=1738950715-YYmKAShuNwliCBfiffIxkaVr5qUl9Tvg-0-82b8748c7dd85cdb01503576bd738330)
图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=1738950715-Js4bLjLzAc4KOc6Nfa10OPaipDFtsHGS-0-21b61d7c91c9e48803dfca472cdb4997)
图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=1738950715-XF7IvMs7aaZWjMnEwjJ7sxC2289eMyHH-0-9046a96289f778b72fed41ebcaf76555)
图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=1738950715-Mw8okcuAXugI96P1CUZdDmrpS42L6iQV-0-2cec511be05bfc568d14ccf55f0be46a)
图4.47 步骤(6)排序过程
(7)接下来对中间值3的左、右两侧排序,排序后的结果如图4.48所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P109_10227.jpg?sign=1738950715-6TaYkgQ15tnSx55LWnPZCFcyoyosYTzG-0-39b9f4250f6e2be647b75492772f558f)
图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=1738950715-PpYy7sW4YnTUaKRvgZzWGqYD3nRIMpfy-0-4846e131d9cf65a5fecc41728f5723df)
图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=1738950715-d7uwVlli0zdQT0qpc9QcDJTgpfpAxMYC-0-a6972ab32119e8c121524631d0a68513)
图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=1738950715-4Sj3nun9TsruxCjsuLJerURY7JzeSHIJ-0-ea56c4fc3e3ece8a89c15351a4f8984d)
图4.51 步骤(10)排序过程
(11)以中间值9为界,分为左右两侧,再进行排序,最后完成右半边排序,如图4.52所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P110_10248.jpg?sign=1738950715-uCmKtX545gRpYpFKytJfPFsMQGPpODx9-0-5e7217131616f656489d6ab5b3625392)
图4.52 步骤(11)排序过程
(12)结合左半边排序和右半边排序,最终的排序结果如图4.53所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P110_10252.jpg?sign=1738950715-7Wq3cQ8sZ1l1SOMYlSDAHmbrJ8AlhJRU-0-624df93bdca9dde3e1eae9593b949935)
图4.53 最终排序结果
【实例4.11】 使用快速排序法将列表中的数字递增排序。(实例位置:资源包\Code\04\11)
用Python代码实现上方示例中的快速排序算法,具体代码如下:
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P110_32969.jpg?sign=1738950715-iOag97kZaZyCK7CGRBbDGtWaYZvbip0x-0-a628175d62ecbee33c22ef6ce207f34d)
运行结果如图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=1738950715-QdDuVWZFsw5tKaAKj4EU9NPXacVB71e1-0-a66b86750fe8648d288628564a7b90f6)
运行结果如图4.55所示。
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P111_10594.jpg?sign=1738950715-nTpYMutyty9zdaZNJPyWl51Orpz4TGxM-0-95042784dbdcd87eb96871a46370a430)
图4.54 快速排序法
![](https://epubservercos.yuewen.com/569667/23721647609535706/epubprivate/OEBPS/Images/Figure-P111_10602.jpg?sign=1738950715-9T15YCAORLZuCQMJ5qepESZtaw9gNTpH-0-be1187075b8b6347f7fd5ae1991ef30b)
图4.55 运行结果