数据结构(10)---归并排序

归并排序

思路:
一. 分而治之
先拆后合并,拆分成一个元素一个元素
1.拆分
分2组,2组分4组…直到分成数组每个元素都是单着的
2.然后合并
2个元素合并,比较大小,小的在前,依此类推
然后两个一组和另外两个一组比较排序
然后4个一组排序比较

最后全部排序

二. 递归
mid = n // 2
拆分和合并生成的数组是对应的,可以视为merge_sort()后返回的结果是对应的 同样大小的有序数组,
left_list = merge_sort(a[:mid])
right_list = merge_sort(a[mid:])

合并比较具体实现:

如何进行合并比较:

1. 先定义一个列表 list ,存储排序后的结果

用途:用来存储左右两边排序后的结果,将小的按顺序append进来

2.拆分后的数组和指针声明

按左右两个部分来 比如左边列表为 left 右边列表为 right
设置左边指针和右边指针下标都为0

3.比较 left[0] 和right [0]

(1)如果 left[0] < right [0] , list 就 append 小的数 left[0]
然后left指向的指针右移
(2)如果 left[0] > right [0] , list 就 append 小的数 right[0]
然后right指向的指针右移

4.终止条件:全部都比较完毕,

左边和右边指针所指下标都大于等于 left 或者right 长度
即 while left_point<len(left) and right_point<len(right)

5.终止条件的遗漏处理

终止条件会导致list append的数据丢失一个,所以需要处理
list=list+left[left_point:] # 将left指针右侧剩下的数据追加上来
list=list+right[right_point:] # 将right指针右侧剩下的数据追加上来
注意:如果为空,追加的也是[] 空列表,不会报错

程序实现流程梳理:

def merge_sort(a):
    # 拆分实现
    n = len(a)
    # 拆分终止条件: 拆成的长度等于1
    if n <= 1:
        print("不执行")
        return a
    print("哈哈哈")
    mid = n // 2
    print("此时mid为:",mid)
    # 拆分和合并生成的数组是对应的,可以视为merge_sort()后返回的结果是对应的 同样大小的有序数组,
    left_list = merge_sort(a[:mid])
    right_list = merge_sort(a[mid:])
    print("左边序列left_list是:",left_list)
    print("右边序列right_list是:", right_list)

打印结果:

哈哈哈
此时mid为: 2
哈哈哈
此时mid为: 1
不执行
不执行
左边序列left_list是: [2]
右边序列right_list是: [1]
此时:left_list[left],right_list[right]是: 2 1
跳出循环后,list为: [1]
哈哈哈
此时mid为: 1
不执行
不执行
左边序列left_list是: [5]
右边序列right_list是: [4]
此时:left_list[left],right_list[right]是: 5 4

我们可以看到,输入:a = [2,1,5,4]
拿到数组a 后,先判断是不是只有一个元素,
(1)输入的数组不是一个元素
执行mid = n // 2
然后继续 回归,进行拆分
left_list = merge_sort(a[:mid])
right_list = merge_sort(a[mid:])
直到拆分成数组里只有一个一个元素,即left_list是: [2] 时,进入
if n <= 1:
print(“不执行”)
return a
返回单个元素
(2)拆分完毕后,执行 上面的合并比较具体实现
即:
左边拆分,成单个元素,比较,合并
右边拆分,成单个元素,比较,合并

时间复杂度:
最优和最差都是 O(nlogn)

具体实现:

def merge_sort(a):
    # 拆分实现
    n = len(a)
    # 拆分终止条件: 拆成的长度等于1
    if n <= 1:
        return a
    mid = n // 2
    # 拆分和合并生成的数组是对应的,可以视为merge_sort()后返回的结果是对应的 同样大小的有序数组,
    left_list = merge_sort(a[:mid])
    right_list = merge_sort(a[mid:])
    # 将左右的数组列表进行合并
    list = []
    left=0
    right = 0
    while left<len(left_list) and right<len(right_list):
        if left_list[left] < right_list[right]:
            list.append(left_list[left])
            left += 1
        else:
            list.append(right_list[right])
            right += 1
    list=list+left_list[left:]
    list = list + right_list[right:]
    return list

if __name__ == "__main__":
    a = [2, 1, 8, 7, 9, 5]
    print(a)
    x=merge_sort(a)
    print(x)

输出结果为:

[2, 1, 8, 7, 9, 5]
[1, 2, 5, 7, 8, 9]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值