当前位置: 首页 > news >正文

排序算法归并排序

归并排序详解

归并排序(Merge Sort)是一种 ​​分治算法​​,核心思想是将数组不断拆分为更小的子数组排序,再合并成有序数组。时间复杂度始终为 ​O(n log n)​,稳定且效率高。


工作步骤:

  1. ​分解​​:将数组从中点分为左右两部分
  2. ​递归​​:对左右子数组分别递归排序
  3. ​合并​​:将两个有序子数组合并为一个有序数组

案例:整理扑克牌

假设你有两堆已排序的扑克牌(左堆:[3, 5], 右堆:[1, 8])需合并为一副有序牌:

  1. 比较两堆顶部的牌:左堆3 > 右堆1 → 取1放到新堆
  2. 再比较:左堆3 < 右堆8 → 取3
  3. 左堆剩5 < 8 → 取5
  4. 最后取右堆剩余的8 → 新堆[1, 3, 5, 8]

Python 代码实现

def merge_sort(arr):# 递归终止条件:单元素或空数组if len(arr) <= 1:return arrmid = 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# 双指针遍历左右数组while i < len(left) and j < len(right):if left[i] <= right[j]:result.append(left[i])i += 1else:result.append(right[j])j += 1# 添加剩余元素result.extend(left[i:])result.extend(right[j:])return result# 测试示例
if __name__ == "__main__":array = [38, 27, 43, 3, 9, 82, 10]print("原始数组:", array)sorted_array = merge_sort(array)print("排序结果:", sorted_array)

输出示例:

原始数组: [38, 27, 43, 3, 9, 82, 10]
排序结果: [3, 9, 10, 27, 38, 43, 82]

算法关键点

  1. ​稳定性​​:left[i] <= right[j] 保证相等元素顺序不变
  2. ​空间代价​​:需额外 O(n) 空间存储合并结果
  3. ​高效场景​​:大数据量排序(远超冒泡/插入排序)

💡 ​​现实应用​​:数据库排序、外排序(处理超大数据)
🔄 分治思想同样适用于快速排序,但归并的稳定性是其独特优势。


做题

我们需要对数组 a = {6, 5, 4, 3, 2, 1, 8, 8} 进行归并排序(升序),并找出​​完成最终归并排序的前一步的结果​​。


归并排序的基本步骤

  1. ​分解​​:将数组递归地分成两半,直到每个子数组只有一个元素
  2. ​合并​​:将两个已排序的子数组合并成一个有序数组

具体过程

初始数组:[6, 5, 4, 3, 2, 1, 8, 8]

  1. 第一次分解:

    • 左半部分:[6, 5, 4, 3]
    • 右半部分:[2, 1, 8, 8]
  2. 对左半部分 [6, 5, 4, 3] 分解:

    • 左:[6, 5] → 排序后:[5, 6]
    • 右:[4, 3] → 排序后:[3, 4]
    • 合并:[5, 6][3, 4][3, 4, 5, 6]
  3. 对右半部分 [2, 1, 8, 8] 分解:

    • 左:[2, 1] → 排序后:[1, 2]
    • 右:[8, 8] → 排序后:[8, 8]
    • 合并:[1, 2][8, 8][1, 2, 8, 8]
  4. ​最终合并的前一步​​:

    • 左半部分已排序:[3, 4, 5, 6]
    • 右半部分已排序:[1, 2, 8, 8]
    • 下一步是将 [3, 4, 5, 6][1, 2, 8, 8] 合并为 [1, 2, 3, 4, 5, 6, 8, 8]

因此,​​完成最终归并排序的前一步的结果​​是:

  • 左半部分:[3, 4, 5, 6]
  • 右半部分:[1, 2, 8, 8]

选项匹配

  • 2, 1, 8, 8, 6, 5, 4, 3:错误,未体现归并排序的合并过程。
  • 3, 4, 5, 6, 1, 2, 8, 8:正确,这是左半部分和右半部分分别排序后的结果。
  • 1, 2, 3, 4, 5, 6, 8, 8:错误,这是最终排序结果,不是前一步。
  • 6, 5, 4, 3, 2, 1, 8, 8:错误,这是初始数组。

正确答案:​​Ⓑ 3, 4, 5, 6, 1, 2, 8, 8​

http://www.lryc.cn/news/612398.html

相关文章:

  • 单变量单步时序预测:CNN-BiGRU卷积神经网络结合双向门控循环单元
  • 202506 电子学会青少年等级考试机器人六级实际操作真题
  • 基于RPR模型的机械臂手写器simulink建模与仿真
  • Qt Frameless Widget跨平台无边框窗口
  • 机器学习-KNN​​
  • 云平台托管集群:EKS、GKE、AKS 深度解析与选型指南-第四章
  • iT 运维: WindoWs CMD 命令表
  • Flutter开发 Image组件使用示例
  • <form> + <iframe> 方式下载大文件的机制
  • 基于Github Pages搭建个人博客站点:hexo环境搭建、本地预览与发布
  • 当前就业形势下,软件测试工程师职业发展与自我提升的必要性
  • AI 软件工程开发 AI 算法 架构与业务
  • [FBCTF2019]RCEService
  • Kafka-exporter采集参数调整方案
  • android NDK 报错日志解读和还原报错方法名
  • 数语科技登陆华为云商店,助力企业释放数据潜能
  • FPGA学习笔记——VGA彩条显示
  • 【软考系统架构设计师备考笔记4】 - 英语语法一篇通
  • 机器人定位装配的精度革命:迁移科技如何重塑工业生产价值
  • Spring Boot 参数校验全指南
  • 应急响应linux
  • vue3+element-plus,el-popover实现筛选弹窗的方法
  • ACL 2025 Oral|Evaluation Agent:面向视觉生成模型的高效可提示的评估框架
  • 【关于Java的对象】
  • C++、STL面试题总结(二)
  • Android14的QS面板的加载解析
  • 【android bluetooth 协议分析 03】【蓝牙扫描详解 4】【BR/EDR扫描到设备后如何上报给app侧】
  • 力扣137:只出现一次的数字Ⅱ
  • 【计算机网络 | 第4篇】分组交换
  • Javascript/ES6+/Typescript重点内容篇——手撕(待总结)