排序之归并排序

一、概念及其介绍

归并排序(Merge sort)是建立在归并操作上的一种有效、稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

二、适用说明

当有 n 个记录时,需进行 logn 轮归并排序,每一轮归并,其比较次数不超过 n,元素移动次数都是 n,因此,归并排序的时间复杂度为 O(nlogn)。归并排序时需要和待排序记录个数相等的存储空间,所以空间复杂度为 O(n)。

归并排序适用于数据量大,并且对稳定性有要求的场景。

三、过程图示

归并排序是递归算法的一个实例,这个算法中基本的操作是合并两个已排序的数组,取两个输入数组 A 和 B,一个输出数组 C,以及三个计数器 i、j、k,它们初始位置置于对应数组的开始端。

A[i] 和 B[j] 中较小者拷贝到 C 中的下一个位置,相关计数器向前推进一步。

当两个输入数组有一个用完时候,则将另外一个数组中剩余部分拷贝到 C 中。

3

自顶向下的归并排序,递归分组图示:

对第三行两个一组的数据进行归并排序

 对第二行四个一组的数据进行归并排序

整体进行归并排序

 

def merge_sort(arr):
    # 递归函数,对输入的数组进行归并排序
    if len(arr) <= 1:
        return arr  # 如果数组长度小于等于1,直接返回
    mid = len(arr) // 2  # 找到数组中间位置
    left = merge_sort(arr[:mid])  # 递归地对左半部分进行归并排序
    right = merge_sort(arr[mid:])  # 递归地对右半部分进行归并排序
    return merge(left, right)  # 合并左右两部分的结果

def merge(left, right):
    # 辅助函数,合并两个有序数组
    result = []  # 用于存储合并后的结果
    i, j = 0, 0  # 初始化两个指针

    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])  # 将左侧较小元素加入结果
            i += 1
        else:
            result.append(right[j])  # 将右侧较小元素加入结果
            j += 1

    result.extend(left[i:])  # 将剩余的左侧元素添加到结果数组
    result.extend(right[j:])  # 将剩余的右侧元素添加到结果数组

    return result  # 返回合并后的有序数组

arr = [7, 2, 5, 1, 8, 4]
sorted_arr = merge_sort(arr)
print(sorted_arr)  # 输出排序后的数组
 
 

当我们调用 ​merge_sort([7, 2, 5, 1, 8, 4])​ 时,会按照以下步骤执行归并排序:

  1. 初始数组为 ​[7, 2, 5, 1, 8, 4]​。
  2. 进行第一次递归:
    • 分成两个子数组 ​[7, 2, 5]​ 和 ​[1, 8, 4]​。
    • 对左侧子数组 ​[7, 2, 5]​ 调用 ​merge_sort()​ 进行递归。
      • 再次进行递归拆分,得到子数组 ​[7]​、​[2, 5]​。
      • ​[2, 5]​ 进行递归拆分,得到子数组 ​[2]​、​[5]​。
      • 合并子数组 ​[2]​ 和 ​[5]​,得到有序数组 ​[2, 5]​。
      • 最后,合并子数组 ​[7]​ 和 ​[2, 5]​,得到有序数组 ​[2, 5, 7]​。
    • 对右侧子数组 ​[1, 8, 4]​ 也进行相同的递归拆分、合并操作。
      • 拆分得到子数组 ​[1]​、​[8, 4]​。
      • 继续拆分,得到子数组 ​[8]​、​[4]​。
      • 合并 ​[8]​ 和 ​[4]​,得到 ​[4, 8]​。
      • 最后,合并 ​[1]​ 和 ​[4, 8]​,得到 ​[1, 4, 8]​。
  3. 现在,我们已经获得了两个有序的子数组 ​[2, 5, 7]​ 和 ​[1, 4, 8]​。
  4. 最后一步是合并这两个有序数组:
    • 从两个数组中各取出一个元素进行比较,将较小的元素添加到结果数组中。
    • 在这种情况下,我们首先取出来的是2和1,所以将1添加到结果数组中。
    • 然后,从原数组取出5和4,将4添加到结果数组。
    • 重复上述过程,将剩余的所有元素添加到结果数组中。
  5. 最终,我们获得了完全排序的数组 ​[1, 2, 4, 5, 7, 8]​。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

量子边缘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值