2.7 算法 --9 归并排序

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

 
20155953-4e3f4311d981ec63.jpg
归并排序流程图

归并排序思路

1.满足归并排序输入的(一个无序列表里面有两个有序列表),直接使用归并算法处理。
2.两个有序列表混合排序,将两个列表当做两个有序区,使用归并算法处理。
3.将一个无序列表排序,需要先分解再合并。

 

 
20155953-932b2c3ba3742166.png
分解与合并

 

代码

#归并算法
def merge(li,low,mid,high):
    '''
    :param li:排序的列表
    :param tmp:首元素
    :param mid: 第一段有序末位
    :param high: 尾元素
    :return:
    '''
    i = low        #tmp1
    j = mid + 1    #tmp2
    li_tmp = []    #有序列表
    #出循环的情况是,第一个列表空了,或者第二个列表空了。
    while i <= mid and j <= high:
        #如果第二个列表的元素大于第一个列表的元素,就把第一个列表里的元素放到有序区,然后第一个列表索引+1
        if li[i] <= li[j]:
            li_tmp.append(li[i])
            i += 1
        else:
            li_tmp.append(li[j])
            j += 1
    #这里是看两个列表,如果有一个空了,另一个还有没有元素,有的话就全放到有序区。
    while i <= mid:
        li_tmp.append(li[i])
        i += 1
    while j <= high:
        li_tmp.append(li[j])
        j += 1
    # it_tmp[0:]=li[low:high+1]
    #然后把有序区覆盖掉原来的列表,这样就不用返回列表了。
    for i in range(low,high+1):
        li[i] = li_tmp[i-low]

#两个有序列表
def merge_list(li1,li2):
    '''
    列表再多点的话,推荐reduce()函数。
    :param li1:
    :param li2:
    :return:
    '''
    li = []
    i = 0
    j = 0
    while i <len(li1) and j < len(li2):
        if li[i] <= li[j]:
            li.append(li1[i])
            i += 1
        else:
            li.append(li2[j])
            j += 1
    while i <= len(li1):
        li.append(li1[i])
        i += 1
    while j <= len(li2):
        li.append(li2[j])
        j += 1

#一个无序列表
def merge_sort(li,low,high):
    '''
    把一个乱序列表两个一半长度的有序列表。(让一个列表满足归并的条件)
    分解与合并。
    :param li:
    :param low:
    :param high:
    :return:
    '''
    if low < high:
        mid = (low + high) // 2
        merge_sort(li,low,mid)
        merge_sort(li,mid+1,high)
        merge(li,low,mid,high)

总结

稳定性:归并排序是一种稳定排序。

比较性:因为排序时元素之间需要比较,所以是比较排序。
此外,归并排序中的比较次数是所有排序中最少的。原因是,它一开始是不断地划分,比较只发生在合并各个有序的列表时。

时间复杂度:T(N) = 2T(N/2) + O(N) 可知时间复杂度为O(NlogN)
列表的初始顺序会影响到排序过程中的比较次数,但是总的而言,对复杂度没有影响。平均情况 or 最坏情况下 它的复杂度都是O(NlogN)

空间复杂度:归并排序中,用到了一个临时列表,故空间复杂度为O(N)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

寒 暄

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

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

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

打赏作者

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

抵扣说明:

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

余额充值