2.7 算法 --7 快速排序

算法子目录:https://blog.csdn.net/qq_41106844/article/details/105553931

 
20155953-6a1cf2d2d3e28ede.jpg
快速排序流程图

代码:

from cat_time import cal_time
import random

def quick_sort(li,letf,right):
    if letf<right:   #确保列表长度大于等于2
        mid = partition(li,letf,right)
        # 对列表两边的元素继续快排
        quick_sort(li,letf,mid-1)
        quick_sort(li,mid+2,right)


def partition(li,left,right):
    #选取 pivot 元素
    tmp = li[left]
    #大循环的条件是left 小于 right  用来控制一旦left和right重合,就结束排序
    while left < right:
        #右边的元素小于 tmp 元素  交换元素, 同时right-1
        while left < right and li[right] >= tmp:
            right -= 1
        li[left] = li[right]
        #同理
        while left < right and li[left] <= tmp:
            left += 1
        li[right] = li[left]
        #因为 left = right 所以返回谁都一样
        return left
@cal_time
#递归算法要穿马甲来计时
def quick_sort_mj(li):
    quick_sort(li,0,len(li)-1)

li = list(range(10000))
random.shuffle(li)
quick_sort_mj(li)
---------------
输出结果:
quick_sort_mj running time:0.033910512924194336 secs.

之前三个“low B”算法要算3秒,现在只需要0.03秒。

使用lambda的快排

import random

quick_sort = lambda array: array if len(array) <= 1 else quick_sort([
    item for item in array[1:] if item <= array[0]
]) + [array[0]] + quick_sort([item for item in array[1:] if item > array[0]])


li = list(range(10000))
random.shuffle(li)
quick_sort(li)

匿名函数就是装一下用的,复杂度过高,还占用空间,速度比普通的三种排序快一点。

使用列表推导式的快排

from cat_time import cal_time
import random

def quick_sort2(li):
    if len(li) <= 2:
        return li
    tmp = li[0]
    left = [v for v in li[1:] if v <= tmp]
    right = [v for v in li[1:] if v <= tmp]
    left = quick_sort2(left)
    right = quick_sort2(right)
    return left + [tmp] +right

@cal_time
#递归算法要穿马甲来计时
def quick_sort_mj2(li):
    quick_sort2(li)


li = list(range(10000))
random.shuffle(li)
quick_sort_mj2(li)

防超出递归深度,因为使用C的组件较多,速度比普通写法还要快一点(大约15%),但是空间复杂度变成了O(n)。

总结

稳定性:快排是一种不稳定排序,比如基准值的前后都存在与基准值相同的元素,那么相同值就会被放在一边,这样就打乱了之前的相对顺序

比较性:因为排序时元素之间需要比较,所以是比较排序

时间复杂度:快排的时间复杂度为O(nlogn),最坏情况是O(n2),直接造成栈溢出,Python停止运行。
解决方法是: pivot 从列表里随便选一个,然后和left交换。

空间复杂度:排序时需要另外申请空间,并且随着数列规模增大而增大,其复杂度为:O(nlogn)

归并排序与快排 :归并排序与快排两种排序思想都是分而治之。

但是它们分解和合并的策略不一样:归并是从中间直接将数列分成两个,而快排是比较后将小的放左边大的放右边,所以在合并的时候归并排序还是需要将两个数列重新再次排序,而快排则是直接合并不再需要排序,所以快排比归并排序更高效一些,可以从示意图中比较二者之间的区别。

快速排序有一个缺点就是对于小规模的数据集性能不是很好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

寒 暄

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

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

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

打赏作者

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

抵扣说明:

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

余额充值