排序之快速排序

6 篇文章 5 订阅
2 篇文章 0 订阅


快速排序一般是单轴排序,还有改进的双轴排序

快速排序之所以比较快,是因为相比冒泡排序,每次交换都是跳跃式的,每次排序的时候设置一个基准点,将小于等于及诊断的数全部放在基准点的左边,将大于等于基准点的数全部放在基准点的右边。这样在每次交换的时候就不会像冒泡排序那样每次都只能在相邻的数之间进行交换,交换的距离就打的多了,因此总的交换次数就小了,速度自然就提高了。当然在最坏的情况下,仍可能是相邻的两个数进行交换。因此快速排序的最差时间复杂度和冒泡排序是一样的都是 O ( n 2 ) O(n^2) O(n2),它的平均时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)
在这里插入图片描述

单轴快排

版本一(按照自己理解写的):

def part(arr, low, high):
    if low > high:
        return arr
    
    pivot = arr[low] # 轴,这里选数组开头第一个
    while low < high:
        # 因为是开头是轴,所以从右边high开始对比,找个比轴小的
        while low < high and arr[high] >= pivot: # 这里一定要加等于号(=)
            high -= 1
        arr[low], arr[high] = arr[high], arr[low]

        # 然后从左边开始,找个比轴大的,这样交替进行
        while low < high and arr[low] <= pivot:
            low += 1
        arr[low], arr[high] = arr[high], arr[low]
    return low # 当跳出循环的时候low=high

def Quick_Sort_me(arr, start, end):
    if start < end: # 一定要小心,这里也需要判断
        pi = part(arr, start, end)
        Quick_Sort_me(arr, start, pi-1) # 这里是pi-1,因为排序一次,轴的位置已经就定了
        Quick_Sort_me(arr, pi+1, end)

上面分成两种的写法,比较容易犯错,可能会少判断条件, 下面把这两个函数写到一块

def Quick_sort_upVer(arr, low, high):
    if low >= high:
        return arr

    pivot = arr[low]
    i, j = low, high
    while low < high:
        while low < high and arr[high] >= pivot:
            high -= 1
        arr[high], arr[low] = arr[low], arr[high]

        while low < high and arr[low] <= pivot:
            low += 1
        arr[high], arr[low] = arr[low], arr[high]

    Quick_sort_upVer(arr, i, low-1) # 注意这里是i
    Quick_sort_upVer(arr, low+1, j) # 注意这里是j
    return arr

版本二

这个版本网上好多,说实话个人觉得比较绕

def quick_sort(lists,i,j):
    if i >= j:
        return list
    pivot = lists[i]
    low = i
    high = j
    while i < j:
        while i < j and lists[j] >= pivot:
            j -= 1
        lists[i]=lists[j]
        while i < j and lists[i] <=pivot:
            i += 1
        lists[j]=lists[i]
    lists[j] = pivot
    quick_sort(lists,low,i-1)
    quick_sort(lists,i+1,high)
    return lists

作者:影zero
链接:https://zhuanlan.zhihu.com/p/63227573

版本三(算法导论)

def partition(arr, low, high):
    i = (low - 1) # 最小元素索引
    pivot = arr[high]

    for j in range(low, high):
        # 当前元素小于或等于pivot
        if arr[j] <= pivot:
            i = i+1
            arr[i], arr[j] = arr[j], arr[i]
    arr[i+1], arr[high] = arr[high], arr[i+1] # 因为是range所以上面循环取不到最右边的数
    return i+1

def quickSort(arr, low, high):
    if low < high:
        pi = partition(arr, low, high)
        quickSort(arr, low, pi-1)
        quickSort(arr, pi+1, high)

理解参考下图:图源
在这里插入图片描述
就是底下参考视频里第一个方法

双轴快排

Java中的Arrays.sort中,当数组长度大于286的时候才使用双轴快排
未完待续

参考

1:马士兵说:快速排序与双轴快排
2:马士兵说:扩展内容-双轴快排

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值