面试必备算法|图解快速排序(Python)

快速排序

快速排序的思想

​ 快速排序通过一次排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。具体步骤如下:

  • 从数列中挑出一个元素,称为"基准"(pivot);
  • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区操作;
  • 递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。

图解快速排序

​ 这里展示放置第一个基准的过程,首先选择第一个数字作为基准。

在这里插入图片描述

​ 接下来我们在26和20的位置分别设置两个指针low和high,并用maddle来存储基准的值(使得列表中基准的位置可以用于元素替换)

在这里插入图片描述

​ 现在我们的目的是让小的数字在前面,大的数字在后面,鉴于我们现在在第一个基准的位置可以用于元素的替换(此处可以看作为空),所以我们从high指针开始进行操作(遍历向前直到找到比基准小的数字)。

在这里插入图片描述

​ 此时我们可以知道high的位置为空,也就是说high的位置可以用作下一个元素的存储位置,因此此时我们转换到操作low指针,通过low指针找到比基准54大的元素。

在这里插入图片描述

​ 和上面同样的原理,我们再继续操作high指针(这里展示剩下交换的过程,如果理解交换过程可以跳过)

在这里插入图片描述

​ 最后如果我们再把指针进行左移操作,就会使得low和high指针重合,此时重合的位置也就是我们最开始找到的基准(54)的位置,至此,我们就可以把基准(54)放到该位置上了。

在这里插入图片描述

​ 此时我们会发现在54前面的数字都比54小,后面的数字都比54大,这也就证明我们已经找好了54的位置,后续我们将54作为切分点,把前面和后面分成两个子列表并递归的执行上诉同样思想的操作就可以了。

快速排序的性质

最优时间复杂度: O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)
最坏时间复杂度: O ( n 2 ) O(n^2) O(n2)
稳定性:不稳定

快速排序代码实现

# start/end表示起始指针的位置(不是具体的值)
lst = list(map(int, input().split(',')))


def quick_sort(alist, start, end):
    # 如果前指针的位置大于等于后指针的位置

    if start >= end:
        return

    low = start
    high = end
    middle = alist[low]

    while low < high:
        while low < high and alist[high] >= middle:
            high -= 1
        alist[low] = alist[high]
        while low < high and alist[low] <= middle:
            low += 1
        alist[high] = alist[low]
    alist[low] = middle

    quick_sort(alist, start, low - 1)
    quick_sort(alist, low + 1, end)


quick_sort(lst, 0, len(lst) - 1)
print(lst)
快速排序是一种常用的排序算法,它的基本思想是分而治之(Divide and Conquer)。快速排序的基本步骤如下: 1. 选择一个基准值,将数组分为两部分,一部分小于基准值,一部分大于基准值。 2. 对这两部分继续进行快速排序,直到整个数组有序。 下面是使用Python实现快速排序的代码: ```python def quicksort(arr): if len(arr) <= 1: return arr else: pivot = arr less = [x for x in arr[1:] if x <= pivot] greater = [x for x in arr[1:] if x > pivot] return quicksort(less) + [pivot] + quicksort(greater) ``` 这段代码首先检查数组的长度,如果长度小于等于1,就直接返回数组,因为只有一个元素或没有元素的数组已经是排序好的。否则,选择数组的第一个元素作为基准值,然后将数组分为两部分,一部分是小于等于基准值的元素,另一部分是大于基准值的元素。接着对这两部分分别进行快速排序,最后将排序好的结果合并起来。 使用这个函数可以对一个数组进行原地排序,也就是在原数组上进行排序,而不是创建一个新的排序后的数组。下面是一个使用示例: ```python arr = [5, 2, 9, 1, 5, 6] sorted_arr = quicksort(arr) print(sorted_arr) # 输出:[1, 2, 5, 5, 6, 9] ``` 需要注意的是,快速排序的性能依赖于选择基准值的方式,如果选择不当可能会导致算法的效率降低。此外,快速排序在最坏情况下的时间复杂度为O(n^2),但通常情况下其平均时间复杂度为O(n log n)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

二哥不像程序员

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

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

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

打赏作者

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

抵扣说明:

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

余额充值