快速排序(Python实现)

本文深入解析了快速排序算法的原理和实现过程,通过实例演示了如何将一组无序数据通过快速排序算法变为有序数据,详细解释了算法的时间和空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

快速排序思路

逻辑演示

代码

复杂度分析


快速排序思路

快速排序又称为分割交换排序法,是目前公认最佳的排序法,也是使用“分而治之"的方式,先会在数据中找到一个虚拟的中间值,并按此中间值将所有打算排序的数据分为两部分。其中小于中间值的数据放在一边,而大于中间值的数据放在另一边,再以同样的方式分别处理左右两边的数据,直到排序完成为止。

逻辑演示

以一串数据 72, 6, 57, 88, 60, 42,83, 73, 48, 85 为例进行快速排序,将数据按照数值由小到大的顺序排序。

排序前:

7265788604283734885

我们假设虚拟的中间值总位于未排序部分的最左端,因此,第一次划分的虚拟中间值x应该是72。即 x => 72。

我们将待排序数列的最左端下标变量为left = 0,最右端下标变量为right = length - 1 = 9。同时设置两个游标 i = left, j = right。

因此排序前的数列如下:

7265788604283734885
x, left, iright, j

Step1

我们将游标j缓慢的向左移动,找到一个小于虚拟中间值的数字。显然,当游标j移动到48时,此时48 < 72 = x,因此48就是我们要找的数。此时让游标 i 对应位置的数据值填入48,x仍然保存中间值72。

4865788604283734885
left, ijright

填入数据后,i 向右移动一格。

4865788604283734885
leftijright

接下来我们将游标 i 缓慢的向右移动,找到一个大于虚拟中间值的数字。显然,当游标 i 移动到88时,此时88 > 72 = x,因此88就是我们要找的数。此时让游标 j 对应的位置的数据值填入88。

4865788604283738885
leftijright

( x = 72 )

填入数据后,j 向左移动一格。

4865788604283738885
leftijright

Step2

经过一轮移动后,并没有完全将虚拟中间值72把数列分开。因为此时两个游标并没有遍历完全部数据。

我们继续将游标 j 缓慢的向左移动,重复上面的规则,找到一个小于虚拟中间值的数字。显然,当游标 j 移动到42时,此时 42 < 72 = x,因此42就是我们要找的数。此时让游标 i 对应位置的数据值填入42。

4865742604283738885
leftijright

填入数据后,i 向右移动一格。

4865742604283738885
leftijright

我们继续将 i 缓慢向右移动,来寻找一个大于虚拟中间值的数字。当 i 再次向右移动的时候,我们发现此时 i 和 j 对应的下标重叠了。也就是说,i 左边的数字没有大于虚拟中间值的数字,而 j 右边的数字没有小于虚拟中间值的数字,此时 i 和 j 交汇的点就是本轮排序虚拟中间值所在的位置。将虚拟中间值填入该位置中:

4865742607283738885
lefti, jright

至此,虚拟中间值72找到了它应该所在的位置上。我们使用重复的逻辑对72之前的数列 48, 6, 57, 42, 60 和 72之后的数列 83, 73, 88, 85 进行排序,最终得到排好序的数列。

代码

def quick_sort(array, left, right):
    if left >= right:
        return

    i = left
    j = right
    x = array[i]

    while True:
        # 从j开始向前找一个小于或等于x的数
        while j >= i:
            if array[j] <= x:
                break
            j -= 1
        if i >= j:
            array[i] = x
            break
        array[i] = array[j]
        i += 1

        # 从i开始向后找一个大于x的数
        while i < j:
            if array[i] > x:
                break
            i += 1
        if i >= j:
            array[i] = x
            break
        array[j] = array[i]
        j -= 1

    quick_sort(array, left, i-1)
    quick_sort(array, i+1, right)


if __name__ == '__main__':
    demo = [72, 6, 57, 88, 60, 42, 83, 73, 48, 85]
    quick_sort(demo, 0, len(demo)-1)
    print(demo)

复杂度分析

  • 在最快和平均情况下,时间复杂度为 O(nlog_{2}n) 。最坏情况就是每次挑中的虚拟中间值不是最大就是最小,因而最坏情况下的时间复杂度为 O(n^{2}) 。
  • 快速排序法不是稳定排序法。
  • 在最差情况下,空间复杂度为 O(n) , 而最佳情况为 O(log_{2}n)
  • 快速排序法是平均运行时间最快的排序法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值