[基础算法] 快速排序

快速排序的思想就是,每一轮指定一个基准(Pivot)数,然后把小于基准数的数都放到基准数的左边,把大于基准数的数都放到基准数的右边,然后把基准数左边和右边的子数组通过递归的方式按照上述方法进行排序,最终实现整个数组有序。

在这里插入图片描述

输入:[49, 38, 65, 97, 76, 13, 27, 49]

首先指定一个基准数,单独拿出来,通常选择左边第一个,这里就是49。

方便描述,定义一个左指针 i i i,右指针 j j j

然后 j j j从右向左扫描,找到第一个比49要小的数,找到27,放到基准数的位置:
[27, 38, 65, 97, 76, 13, -, 49]

然后 i i i从左向右扫描,找到第一个比49要大的数,找到65,放到上一步空出来的位置:
[27, 38, -, 97, 76, 13, 65, 49]

再次 j j j从右向左扫描,找到第一个比49要小的数,找到13,放到上一步空出来的位置:
[27, 38, 13, 97, 76, -, 65, 49]

再次 i i i从左向右扫描,找到第一个比49要大的数,找到97,放到上一步空出来的位置:
[27, 38, 13, -, 76, 97, 65, 49]

直到 i i i j j j碰头。

最后把基准数放到上一步空出来的位置:
[27, 38, 13, 49, 76, 97, 65, 49]

至此完成一轮。

一轮之后,在Pivot左边的数都小于或等于 49,右边的数都大于或等于49。

然后把左边的数组和右边的数组,用递归的方法,分别进行上述的排序过程。

按照这个思路,很方便写出以下代码:

def quick_sort(nums, left, right):
    
    pivot = nums[left]
    i = left
    j = right
    
    while i < j:
        # 右指针j
        while nums[j] >= pivot and j > i:
            j -= 1
        nums[i] = nums[j]
        i += 1
        # 左指针i
        while nums[i] <= pivot and i < j:
            i += 1
        nums[j] = nums[i]
        j -= 1
    
    # 一轮的最后把Pivot赋值到空出来的位置
    nums[i] = pivot

    # Pivot左边
    quick_sort(nums, left, i - 1)
    # Pivot右边
    quick_sort(nums, i + 1, right)


if __name__ == '__main__':
    nums = [49, 38, 65, 97, 76, 13, 27, 49]
    quick_sort(nums, 0, len(nums) - 1)
    print(nums)

但是有些边界条件需要注意:

首先,从右向左扫描或者从左向右扫描的时候,扫完发现没有符合条件数字,那就不能进行移动操作,所以移动前需要加判断:

if j > i:
   nums[i] = nums[j]
   i += 1

if i < j:
   nums[j] = nums[i]
   j -= 1

另外,在下一轮递归前,要确保输入至少有两个数:

if left < i-1:
	quick_sort(nums, left, i - 1)
if i+i < right:
	quick_sort(nums, i + 1, right)

完整代码:

def quick_sort(nums, left, right):
    pivot = nums[left]
    i = left
    j = right
    while i < j:
        while nums[j] >= pivot and j > i:
            j -= 1
        if j > i:
            nums[i] = nums[j]
            i += 1
        while nums[i] <= pivot and i < j:
            i += 1
        if i < j:
            nums[j] = nums[i]
            j -= 1
    nums[i] = pivot
    if left < i-1:
        quick_sort(nums, left, i - 1)
    if i+i < right:
        quick_sort(nums, i + 1, right)

if __name__ == '__main__':
    nums = [49, 38, 65, 97, 76, 13, 27, 49]
    quick_sort(nums, 0, len(nums) - 1)
    print(nums)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

手撕机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值