归并排序

归并是一种典型的序列操作,其工作是把两个或更多有序序列合并为一个有序序列。基于归并的思想也可也实现排序,称为归并排序。其排序思想如下:

  • 初始时,把待排序序列中的 n 个记录看成 n 个有序子序列,每个子序列的长度均为1。
  • 把当时序列组里的有序子序列两两归并,完成一遍后序列组里的排序序列个数减半,每个子序列的长度加倍。
  • 对加长的有序子序列重复上面的操作,最终得到一个长度为 n 的有序序列。

这种归并方法称为简单的二路归并排序,也可考虑三路归并排序。

程序实现

  • Python
def merge_sort(ls):
    if len(ls) <= 1:
        return ls
    mid = len(ls)//2
    # 序列左边部分
    left = merge_sort(ls[:mid])
    # 序列右边部分
    right = merge_sort(ls[mid:])
    return merge(left,right)

def merge(left,right):
    ## left部分的指针 l right部分的指针 r
    l,r = 0,0
    res = []
    while l < len(left) and r < len(right):
        if left[l] < right[r]:
            res.append(left[l])
            l += 1
        else:
            res.append(right[r])
            r += 1
    res += left[l:]
    res += right[r:]
    return res
ls = [4,7,3,3,50,9,4,8,-1,0,12,2,88]
print(merge_sort(ls))

三路并排

def merge_sort3(ls):
    if len(ls) <= 1:
        return ls
    num = len(ls)//3
    # 序列左边部分
    left = merge_sort(ls[:num])
    # 序列中间部分
    mid = merge_sort(ls[num:2*num])
    # 序列右边部分
    right = merge_sort(ls[2*num:])
    return merge3(left,mid,right)

def merge3(left,mid,right):
    l,m,r = 0,0,0
    res = []
    while l<len(left) and m<len(mid) and r<len(right):
        if left[l] < right[r]:
            if left[l] > mid[m]:
                res.append(mid[m])
                m += 1
            else:
                res.append(left[l])
                l += 1
        else:
            if right[r] > mid[m]:
                res.append(mid[m])
                m += 1
            else:
                res.append(right[r])
                r += 1
    hh = [i for i in [left[l:],mid[m:],right[r:]] if i != []]
    A,B = hh[0],hh[1]
    a,b = 0,0
    while a<len(A) and b<len(B):
        if A[a] > B[b]:
            res.append(B[b])
            b += 1
        else:
            res.append(A[a])
            a += 1
    res += A[a:]
    res += B[b:]
    return res
ls = [4,7,3,3,50,9,4,8,-1,0,12,2,88]
print(merge_sort3(ls))

复杂度和稳定性

  • 复杂度:O(n log n)

  • 稳定性: 稳定