快速排序(Quicksort)是对冒泡排序的一种改进。快速排序由C. A. R. Hoare在1962年提出。采用了分治法。
基本思想:
- 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,
- 然后再按此方法对这两部分数据分别进行快速排序,
- 整个排序过程可以递归进行,以此达到整个数据变成有序序列。
在一篇博客上看到给出的一种快速排序的方法快速排序(过程图解)但感觉复杂化了
举例子:
对序列:9,4,3,7,6,8,5进行快速排序
先选一个基准(这里每次基准都选第一个数值),选9,然后设置两个哨兵
i
,
j
i,j
i,j,
i
i
i从序列左边开始探测,直到找到大于基准9的值,
j
j
j从右边开始探测,知道找到小于基准9的值,即:
9 | 4 | 3 | 7 | 6 | 8 | 5 |
---|---|---|---|---|---|---|
基准 | i , j i,j i,j |
此时, i , j i,j i,j都处于4的位置,说明9后面的值都比9小,交换9和4的位置。9的位置不再动,然后以4为基准:
5 | 4 | 3 | 7 | 6 | 8 | 9 |
---|---|---|---|---|---|---|
基准 | j j j | i i i |
由于 i > j i>j i>j,3和7不交换,基准5插入3/7中间,此时序列分为了两部分(4,3)(7,6,8)
4 | 3 | 5 | 7 | 6 | 8 | 9 |
---|---|---|---|---|---|---|
基准 | i , j i,j i,j | – | 基准 | j j j | i i i | – |
(4,3)中 i , j i,j i,j在同一位置,小于4,交换4和3,(7,6,8)中, i > j i>j i>j,7插入6/8中
3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|
基准 | – | – | 基准 | – | 基准 | – |
此时被分为了三个长度为1的序列(3)(6)(8),排序结束。
比较简单易懂的一种快速排序:
- 选取中间值作为基准值(基准值可以随便选),取出基准值。
- 数列从第一个元素开始和基准值进行比较,小于基准值,那么将它放入左边的分区中,第二个元素比基准值大,把它放入右边的分区中。
- 然后依次对左右两个分区进行再分区,直到最后只有一个元素。
- 分解完成再一层一层返回,返回规则是:左边分区+基准值+右边分区。
以2,5,9,3,7,1,5为例:
2 | 5 | 9 | 3 | 7 | 1 | 5 |
---|---|---|---|---|---|---|
基准 |
2 | 1 | 3 | 5 | 9 | 7 | 5 |
---|---|---|---|---|---|---|
– |
2 | 1 | 3 | 5 | 9 | 7 | 5 |
---|---|---|---|---|---|---|
基准 | – | 基准 |
1 | 2 | 3 | 5 | 5 | 7 | 9 |
---|---|---|---|---|---|---|
– | 基准 | – | 基准 | – | 基准 |
从这可以看出,快速排序是不稳定的:
1 | 2 | 3 | 5 | 5 | 7 | 9 |
---|---|---|---|---|---|---|
– | – | – | – | 基准 | – | – |
python代码实现:
'''快速排序'''
def Quicksort(nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
if len(nums)<2:return nums
mid = len(nums)//2
jizhun = nums[mid]
nums.pop(mid)
left, right = [], []
for i in range(len(nums)):
if nums[i]>jizhun:
right.append(nums[i])
else:
left.append(nums[i])
return Quicksort(left)+[jizhun]+Quicksort(right)