归并排序

列表归并

一个列表分成两部分,这两部分是分别是有序的,但整个列表不是有序的。采用归并的方式让这个列表有序。

li = [2, 3, 6, 8, 1, 4, 5, 7]  # 2,3,6,8有序; 1,4,5,7有序

# 实现归并
def merge(li, low, mid, high):
    """
    两段有序列表的的合并
    :param li:
    :param low: 列表起始位置
    :param mid: 分段处
    :param high: 列表最后位置
    :return: 合并好的有序列表
    """
    i = low             # 前段有序的哨兵
    j = mid + 1         # 后段有序的哨兵
    ltmp = []
    while i <= mid and j <=high:
        if li[i] < li[j]:
            ltmp.append(li[i])
            i += 1
        else:
            ltmp.append(li[j])
            j += 1
    # 退出上面while循环说明有一边已经结束
    # 下面的两个while寻汗只有一会执行
    while i <= mid:
        ltmp.append(li[i])
        i += 1
    while j <= high:
        ltmp.append(li[j])
        j += 1
    # 将排序好的列表在切回去
    li[low: high+1] = ltmp
 
# 测试
li = [2, 3, 6, 8, 1, 4, 5, 7]
merge(li, 0, 3, len(li)-1)
print(li)

# output:
[1, 2, 3, 4, 5, 6, 7, 8]

上述归并的时间复杂度是:O(n)


归并排序

# 分解:将列表越分越小,直至分成一个元素。 
# 终止条件:一个元素是有序的。 
# 合并:将两个有序列表归并,列表越来越大。


代码实现

# -*- coding: utf-8 -*-
# created by X. Liu on 2020/3/15

import random

def merge(li, low, mid, high):
    i = low             # 前段有序的哨兵
    j = mid + 1         # 后段有序的哨兵
    ltmp = []
    while i <= mid and j <=high:
        if li[i] < li[j]:
            ltmp.append(li[i])
            i += 1
        else:
            ltmp.append(li[j])
            j += 1
    while i <= mid:
        ltmp.append(li[i])
        i += 1
    while j <= high:
        ltmp.append(li[j])
        j += 1
    li[low: high+1] = ltmp


def merge_sort(li, low, high):
    """
    归并排序,递归思想
    :param li: 
    :param low: 列表第一个索引值
    :param high: 列表最后一个索引值
    :return: None
    """
    if low < high:      # 至少两个元素
        mid = (low + high) // 2
        merge_sort(li, low, mid)
        merge_sort(li, mid+1, high)
        merge(li, low, mid, high)


# 测试
li = list(range(20))
random.shuffle(li)
print(li)
merge_sort(li, 0, len(li)-1)
print(li)

# output:
[2, 7, 13, 14, 4, 16, 15, 17, 12, 6, 0, 10, 8, 5, 3, 11, 19, 9, 18, 1]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

时间复杂度

# 时间复杂度:O(nlogn) 
# 空间复杂度:O(n)

# python的排序sort()基于归并排序实现
posted @ 2020-03-15 17:14  the3times  阅读(143)  评论(0编辑  收藏  举报