【Python】归并排序、快速排序

一、归并排序

1、思路

首先利用递归将一个待排序的列表不断地分成左右两部分,例如ind = [4, 2, 6, 4]这个列表,我们先将它分为[4, 2][6, 4]两部分,然后把[4, 2]再分为[4][2],把[6, 4]分为[6][4],最后把分出来的最小项分别排序并向上返回排序好的列表,最终完成排序

2、代码

def merge_sort(ind: list):
    if len(ind) <= 1:
        return ind
    left_area = ind[:len(ind)//2]
    right_area = ind[len(ind)//2:]
    merge_sort(left_area)
    merge_sort(right_area)
    return sort(left_area, right_area, ind)


def sort(left_area: list, right_area: list, arr: list):
    i, j, m = 0, 0, 0   # i用来记录左边区域的索引, j用来记录右边区域的索引, m用来记录和并列表的索引
    while i < len(left_area) and j < len(right_area):
        if left_area[i] > right_area[j]:
            arr[m] = right_area[j]
            j += 1
        else:
            arr[m] = left_area[i]
            i += 1
        m += 1
    while i < len(left_area):
        arr[m] = left_area[i]
        i += 1
        m += 1
    while j < len(right_area):
        arr[m] = right_area[j]
        j += 1
        m += 1
    return arr


print(merge_sort([1, 2, 3, 4, 5, 56, 3, 3]))   # [1, 2, 3, 3, 3, 4, 5, 56]

二、快速排序

1、思路

首先取出待排序列表的一个数作为中间数,然后把小的放一边(左边区域),大的放一边(右边区域),然后再对左边区域和右边区域进行相同操作(依旧是递归思想),最后完成排序。

拿ind = [3, 5, 2 ,4 ,3]做一个简单的例子

其中,i代表小于所取数的区域的索引;n代表遍历索引;j代表大于所取数的区域的索引

这里我们所取数设为3,首先我们需要将第一位和3相比较,结果为相等,所以我们把n前进一位,但是小于3的区域并没有增加新元素,所以i不变,j自然也不变

然后我们将作为第二位的5与3比较,结果是大于,所以我们把5和j位置的数据交换,并且把j的位置往前挪一位,由于不知道挪过来的这个数和三的大小关系,所以我们不能动n和i的位置

由于换过来的3和3相等,n前进一位,不多赘述

然后再比较2和3,2小于3,所以我们把2和i指向的位置的数交换,n位置前进一位,i位置前进一位,看到这里经过了思考的你也许就能发现了,i指向的位置永远在小于所选数的右边一位,所以可以安心交换位置

最后我们判断4和3的大小和关系,4大于3,所以我们按照上面的方法交换n位置和j位置所对应的数据,j前挪一位

这时,遍历位置n处于大于区域位置j右边,于是我们结束该阶段的排序,并按照得到的i,n,j的位置获得左区域[:i],右区域[j+1:],以及全都是所选数的区域[i:j+1]

然后对各区域进行递归即可

2、代码

def fast_sort(ind: list):
    if len(ind) <= 1:
        return ind
    ind_left, ind_right = partition(ind)
    return fast_sort(ind[:ind_left]) + ind[ind_left:ind_right] + fast_sort(ind[ind_right:])


def partition(ind: list):
    num = ind[-1]
    i = 0  # i 是左侧小于num的数的索引
    j = len(ind) - 1  # j 是大于num的数的索引
    n = 0  # n 是当前遍历数的索引
    while n <= j:
        if ind[n] < num:
            ind[i], ind[n] = ind[n], ind[i]
            n += 1
            i += 1
        elif num < ind[n]:
            ind[j], ind[n] = ind[n], ind[j]
            j -= 1
        else:
            n += 1
    return i, j + 1


print(fast_sort([3, 4, 1, 2, 3, 4, 5, 7, 8, 9, 5, 4, 5, 4, 2, 2, 1, 3, 5, 6, 7, 8]))   # [1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 7, 7, 8, 8, 9]
  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值