自己总结的快速排序,绝对清楚透彻

1. 快速排序(不含重复元素值)

先选start值为基准值ref,从start+1到end区间,双指针i、j交换位置(目的是把比ref小的放左边,比ref大的放右边,其实就是为了找到基准值应该在的位置),然后当i > j 的时候说明全部遍历完了,此时,j所在的位置就是基准值的位置。

找到基准值后,将基准值前后的数组递归调用函数本身,就可以排好序了。

def QuickSort(arr, start, end):
    if start >= end:
        return arr

    ref = arr[start]
    i = start + 1
    j = end

    while i <= j:
        if arr[i] < ref:
            i += 1
            continue
        if arr[j] > ref:
            j -= 1
            continue
        temp = arr[i]
        arr[i] = arr[j]
        arr[j] = temp

    arr[start] = arr[j]
    arr[j] = ref

    QuickSort(arr, start, j - 1)
    QuickSort(arr, j + 1, end)

    return arr

2. 快速排序(含相同元素值)

上面的方法已经不能满足,因为如果有重复元素值会陷入死循环。
采用三向切分,将数组分为三部分:小于当前切分元素(即基准值)的部分,等于当前切分元素的部分,大于当前切分元素的部分

由于基准可能存在重复值,每次遍历多了一个指针,基准所在位置lo。所以三个指针分别为:lo(基准当前位置)、lt(基准后一个值的位置)、gt(数组最后一个值)。
遍历终止条件和一一样:即lt>gt时退出循环。目的也一样:将小于基准值的放前面,大于基准值的放后面,等于基准值的在一起。

遍历有三种情况:
① 基准值lo小于后一个值lt:那么直接将lt所在位置的值与数组最后一个值gt交换,然后gt-1;
② 基准值lo大于基准后一个值lt:lo和lt所在位置的值交换,并且lo+1,lt+1;
③ 基准值lo和后一个值lt相等:说明基准值有重复。lt++

退出循环后,进行递归。
基准前:start, lo-1
基准后:lt, end

def QuickSort2(arr, start, end):
    if start >= end:
        return arr
    lo = start  # 基准
    lt = start + 1  # 基准后一个值
    gt = end  # 数组最后一个值

    while lt <= gt:
        if arr[lo] < arr[lt]:  # 基准小于后一个值,直接将后一个值扔到数组最后,并且gt-1
            temp = arr[lt]
            arr[lt] = arr[gt]
            arr[gt] = temp
            gt -= 1
        elif arr[lo] > arr[lt]:  # 基准大于后一个值,交换这两个值,然后lo、lt都加1
            temp = arr[lo]
            arr[lo] = arr[lt]
            arr[lt] = temp
            lo += 1
            lt += 1
        elif arr[lo] == arr[lt]:  # 基准后一个值加一
            lt += 1

    QuickSort2(arr, start, lo - 1)
	QuickSort2(arr, lt, end)

    return arr

以上就是快速排序的全部内容了。
码字不易,点个赞吧!希望自己转码顺利!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值