🇨🇳
阿臻的学习笔记
  • 🤖AI
    • 📑README
    • 🕒Scheduling
      • 一种JSSP的DRL环境
    • 📜Paper
      • 神经协同过滤
      • 非侵入信号深度学习
      • 肾透析移植机器学习
      • 心理学随机森林
      • P300数据学习
    • ⚒️Pytorch
      • 1.1数据基础
      • 1.2自动梯度
      • 1.3神经网络
      • 1.4模型实现
      • 2数据操作
    • 🛠️Ray+Gym
    • 📃Graph Neural
      • 图神经网络基础
      • Contrastive Multi-View Representation Learning on Graphs
    • 📽️Deep Learning
      • 《第一章》
      • 《第二章》
      • 《第三章》
      • 《第四章》
      • 台湾陈蕴侬视频2020
    • 🔨MXNet
      • 《第一章》《第二章》
      • 《第三章》
      • 《第四章》
      • 《第五章》
      • 《第六章》
      • 《第七章》
      • 《第八章》
      • 《第九章》
      • 《第十章》
  • 👨‍🏭Study
    • 📔Algorithm
      • Leetcode
        • 第一天(乱刷)
        • 第二天(栈)
        • 第三天(栈)
        • 第四天(堆)(贪心)
        • 第五天(贪心)
        • 第六天(贪心)
        • 第七天(排序)
        • 第八天(排序)
        • 第九天(排序)
        • 第十天(位运算)
        • 第十一天(位运算)
        • 第十二天(位运算)
        • 第十三天(位运算)
        • 第十四天(树)
        • 第十五天(树)
        • 第十六天(树)
        • 第十七天(树)
        • 第十八天(树)
        • 第十九天(树)
        • 第二十天(树)
        • 第二十一天(树)
        • 第二十二天(并查集)
        • 第二十三天(并查集)
        • 第二十四天(DFS)(图)
        • 第二十五天(图)(设计)
        • 第二十六天(拓扑)
        • 第二十七天(字典树)
        • 第二十八天(字典树)
        • 第二十九天(树状数组)(二叉搜索树)
        • 第三十天(递归)
        • 第三十一天(脑筋急转弯)
        • 第三十二天(脑筋急转弯)
        • 第三十三天(记忆化)
        • 第三十四天(队列)
        • 第三十五天(队列)
        • 第三十六天(极小化极大)
        • 第三十七天(几何)
        • 第三十八天(蓄水池抽样)
        • 第三十九天(数组)
        • 第四十天(数组)
        • 第四十一天(数组)
        • 第四十二天(数组)
        • 第四十三天(数组)
        • 第四十四天(数组)
        • 第四十五天(数组)
        • 第四十六天(数组)
      • Sort
        • 最小堆
        • 归并排序(merge_sort)
    • 📓Knowledge
      • python补码
    • 🔧Other
      • pythonic语法
      • Ubuntu备忘
由 GitBook 提供支持
在本页

这有帮助吗?

导出为 PDF
  1. Study
  2. Algorithm
  3. Sort

归并排序(merge_sort)

稳定,分解再合并,时间O(nlog^n),空间O(n)

def merge_sorted(arr):
    """归并排序:二分数组+合并两个有序数组
        比较性:排序时元素之间需要比较,所以为比较排序
        稳定性:当左边的元素小于等于右边的元素就把左边的排前面,而原本左边的就是在前面,所以相同元素的相对顺序不变,故为稳定排序
        时间复杂度:O(nlog^n),排序算法下界
        空间复杂度:O(n),在合并子列时需要申请临时空间,而且空间大小随数列的大小而变化
        记忆方法:所谓归并肯定是要先分解,再合并
    Args:
        arr (List): 要进行归并排序的数组

    Returns:
        List: 排序后的arr数组
    """
    if len(arr) == 1:
        return arr
    mid = len(arr) // 2
    left, right = arr[:mid], arr[mid:]
    return merge(merge_sorted(left), merge_sorted(right))


def merge(left, right):
    """合并阶段

    Args:
        left (List): 已经递归二分的有序的左数组,极端情况下只有一个
        right (List): 已经递归二分的有序的右数组,极端情况下只有一个

    Returns:
        List: 合并left和right两个数组的新数组
    """
    res = []
    while len(left) > 0 and len(right) > 0:
        if left[0] < right[0]:
            res.append(left.pop(0))
        else:
            res.append(right.pop(0))
    res += left
    res += right
    return res


print(merge_sorted([1, 7, 9, 10, 3, 4, 5, 3, 4, 2, 3, 8]))
def merge_sort(l, r):
    """快速版本的归并排序(借鉴)

    Args:
        l (int): 最左区间
        r (int): 最右区间(闭而不是开)

    Returns:
        None: 排完在nums上
    """
    # 终止条件
    if l >= r:
        return 0
    # 递归划分
    m = (l + r) // 2
    merge_sort(l, m)
    merge_sort(m + 1, r)
    # 合并阶段
    i, j = l, m + 1
    # 暂存l,r之间的数组
    tmp[l : r + 1] = nums[l : r + 1]
    for k in range(l, r + 1):
        # 左数组遍历结束
        if i == m + 1:
            nums[k] = tmp[j]
            j += 1
        # 右数组遍历结束 或者 左节点小于等于右节点
        elif j == r + 1 or tmp[i] <= tmp[j]:
            nums[k] = tmp[i]
            i += 1
        # 左节点大于右节点
        else:
            nums[k] = tmp[j]
            j += 1
            # res += m - i + 1 # 统计逆序对


nums = [1, 7, 9, 10, 3, 4, 5, 3, 4, 2, 3, 8]
tmp = [0] * len(nums)
merge_sort(0, len(nums) - 1)
print(nums)
上一页最小堆下一页Knowledge

最后更新于2年前

这有帮助吗?

👨‍🏭
📔