归并排序

归并排序

在这里插入图片描述

介绍

假定待排序表含有n个记录,则可以看成是n个有序的子表,每个子表长度为1,然后两两归并,得到 ⌈n/2⌉个长度为2或1的有序表;再两两归并,……如此重复,直到合并成一个长度为n的有序表为止,这种排序方法称为2-路归并排序

步骤

49 38 65 97 76 13 27
  1. 首先将整个序列的每个关键字看成一个单独的有序的子序列
  2. 两两归并,49和38归并成{38 49} ,65和97归并成{65 97},76和13归并成{13 76},27没有归并对象
  3. 两两归并,{38 49}和{65 97}归并成{38 49 65 97},{13,76}和27归并成{13 27 76}
  4. 两两归并,{38 49 65 97}和{13 27 76}归并成{13 27 38 49 65 76 97}

代码实现

def merge_sort(alist):
    if len(alist) <= 1:
        return alist
    """二分"""
    middle = len(alist) // 2
    left = merge_sort(alist[:middle])
    right = merge_sort(alist[middle:])
    print("========left========")
    print(left)
    print("========right========")
    print(right)
    return merge(left, right)


def merge(left, right):
    """合并操作,将两个有序数组left[]和right[]合并成一个大的有序数组"""
    """left与right的index"""
    l, r = 0, 0
    result = []
    while l < len(left) and r < len(right):
        if left[l] < right[r]:
            result.append(left[l])
            l += 1
        else:
            result.append(right[r])
            r += 1
    result += left[l:]
    result += right[r:]
    return result


alist = [49, 38, 65, 97, 76, 13, 27]
print(alist)
sorted_alist = merge_sort(alist)
print(sorted_alist)

运行结果:
[49, 38, 65, 97, 76, 13, 27]
========left========
[38]
========right========
[65]
========left========
[49]
========right========
[38, 65]
========left========
[97]
========right========
[76]
========left========
[13]
========right========
[27]
========left========
[76, 97]
========right========
[13, 27]
========left========
[38, 49, 65]
========right========
[13, 27, 76, 97]
[13, 27, 38, 49, 65, 76, 97]

分析

时间复杂度

一共n个元素

  1. 第1趟归并:子序列长度为2,所以有n/2对子序列,每个子序列需要执行1次Merge, Merge时间复杂度为子序列长度之和即2
    所以第①趟merge的时间复杂度为O(n/2*2)=O(n)

    49 38| 65 97| 76 13| 27 45 
                    n/2对
    
  2. 第2趟归并:子序列长度为4,所以有n/4对子序列,每个子序列需要执行1次Merge,Merge时间复杂度为子序列长度之和即4
    所以第2趟merge的时间复杂度为O(n/4*4)=O(n)

    38 49 65 97| 13 76 27 45 
                    n/4对
    
  3. 第k趟归并:子序列长度为2k,所以有n/2k对子序列
    当n/2k=1时,k=log2n 此时需要归并的两个子序列长度为n/2,只需要一次Merge就能实现整个序列有序。所以一共执行了k=log2n趟排序,每趟排序的时间复杂度都是O(n)

    所以整个归并排序的时间复杂度为O(nlog2n)

空间复杂度

空间复杂度:因为需要将这个待排序序列转存到一个数组,所以需要额外开辟大小为n的存储空间,即空间复杂度为O(n)

稳定性

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值