Python算法入门day4——常见列表算法分析4 归并排序详解

归并排序

1.了解归并

假设现在的列表分两段有序,如何将其合成一个有序列表

上面这张图,按照虚线分开,分成两个有序列表,设计一个代码变成一个有序

【解题思路】

两箭头代表两段有序数列的第一个元素

两端比大小,哪个数小就把那个数放进新列表,以此类推

当某一边没有数时,将其余数依次存入列表中

 

【归并代码实现】

def merge(li,low,mid,high):
    #列表,最开始的值,中间值(第一个有序列表的最后一位),最后面的值

    #将两个有序列表的开头标记出来
    i=low
    j=mid+1#第二段有序数列的开头
    list_1=[]
    while i<=mid and j<=high:#限制条件(开头小于结尾)两边都有数
        if li[i] < li[j]:
            list_1.append(li[i])
            i+=1
        else:
            list_1.append(li[j])
            j+=1
    #while执行完成,,肯定有一部分没数了
    while i<=mid:#左列表还有数
        list_1.append(li[i])
        i+=1
    while j<=high:#右列表还有数
        list_1.append(li[j])
        j+=1
    #再将list_1里的数放回li中
    li[low,high+1]=list_1

 2.归并排序——使用归并

【解题步骤】

1、分解:将列表越分越小,直至分成一个元素

2、终止条件:一个元素是有序的

3、合并:将两个有序列表归并,列表越来越大

 【代码实现】

#归并函数
def merge(li,low,mid,high):
    #列表,最开始的值,中间值(第一个有序列表的最后一位),最后面的值

    #将两个有序列表的开头标记出来
    i=low
    j=mid+1#第二段有序数列的开头
    list_1=[]
    while i<=mid and j<=high:#限制条件(开头小于结尾)两边都有数
        if li[i] < li[j]:
            list_1.append(li[i])
            i+=1
        else:
            list_1.append(li[j])
            j+=1
    #while执行完成,,肯定有一部分没数了
    while i<=mid:#左列表还有数
        list_1.append(li[i])
        i+=1
    while j<=high:#右列表还有数
        list_1.append(li[j])
        j+=1
    #再将list_1里的数放回li中
    li[low:high+1]=list_1

    
def merge_sort(li,low,high):
    #终止条件 只有一个元素
    if low<high:#至少有两个,递归终止条件(只剩一个的时候)
        mid=(low+high)//2#二分查找中间值
        merge_sort(li,low,mid)#递归左边,左边排序
        #print(li[low:high+1])
        merge_sort(li,mid+1,high)#递归右边,右边排序
        #print(li[low:high+1])
        merge(li,low,mid,high)
        #print(li[low:high+1])
        
        
li=list(range(16))
import random
random.shuffle(li)
print(li)
merge_sort(li,0,len(li)-1)

print(li)

 【运行结果】

我打印了每次递归后的结果和归并后的结果。

#递归
[0, 13]
[0, 13]
[4, 12]
[4, 12]
[0, 13, 4, 12]
[0, 4, 12, 13]
[3, 2]
[2, 3]
[8, 11]
[8, 11]
[2, 3, 8, 11]
[2, 3, 8, 11]
[0, 4, 12, 13, 2, 3, 8, 11]
[0, 2, 3, 4, 8, 11, 12, 13]
[6, 10]
[6, 10]
[9, 1]
[1, 9]
[6, 10, 1, 9]
[1, 6, 9, 10]
[7, 5]
[5, 7]
[15, 14]
[14, 15]
[5, 7, 14, 15]
[5, 7, 14, 15]
[1, 6, 9, 10, 5, 7, 14, 15]
[1, 5, 6, 7, 9, 10, 14, 15]
[0, 2, 3, 4, 8, 11, 12, 13, 1, 5, 6, 7, 9, 10, 14, 15] #递归
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] #归并函数


时间复杂度O(nlogn) 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值