news 2026/6/20 4:02:48

Java 归并排序:稳定排序的“秩序守护者“

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java 归并排序:稳定排序的“秩序守护者“

Java 归并排序:稳定排序的"秩序守护者"

分而治之的典范——拆到最小,再有序合并

引言

归并排序(Merge Sort)把数组拆成两半分别排好,再像合并有序链表一样合二为一。

最大优点:稳定 + 稳定 O(n log n)。代价是需要额外 O(n) 空间。

它是少数几个能保证最坏情况也是 O(n log n)的排序算法(不像快排最坏 O(n²)),也是链表排序的最优解(快排对链表不友好)。

这篇文章,我会把归并排序讲透:

  • 用 ASCII 图演示"拆分"和"合并"的完整过程
  • 推导为什么mid = left + (right - left) / 2防溢出
  • 列出 4 个高频易错点(尤其是边界条件)
  • 配套 LeetCode 148(链表归并排序)和 剑指 Offer 51(逆序对)

1. 核心思想:拆到不能再拆,再合并回来

1.1 通俗理解

归并排序的精髓:先递归拆分,再归并合并

想象你要整理一堆混在一起的扑克牌:

1. 把牌堆从中间分成两半 2. 左边那堆继续分两半 3. 右边那堆继续分两半 4. 直到每堆只剩 1 张牌(天然有序) 5. 两两合并,合并时按顺序选小的 6. 最终合成一个有序牌堆

1.2 ASCII 图解演示

以数组[38, 27, 43, 3, 9, 82, 10]为例:

拆分过程(自顶向下): [38, 27, 43, 3, 9, 82, 10] / \ [38, 27, 43, 3] [9, 82, 10] / \ / \ [38, 27] [43, 3] [9, 82] [10] / \ / \ / \ | [38] [27] [43] [3] [9] [82] [10] 合并过程(自底向上): [38] [27] [43] [3] [9] [82] [10] \ / \ / \ / | [27, 38] [3, 43] [9, 82] [10] \ / \ / [3, 27, 38, 43] [9, 10, 82] \ / [3, 9, 10, 27, 38, 43, 82]

1.3 merge 的细节图解

以合并[27, 38][3, 43]为例:

左:[27, 38] 右:[3, 43] temp: [] 步骤 1:左指针 i=0(27),右指针 j=0(3) 27 > 3 → temp = [3],j++ 步骤 2:i=0(27),j=1(43) 27 < 43 → temp = [3, 27],i++ 步骤 3:i=1(38),j=1(43) 38 < 43 → temp = [3, 27, 38],i++ 步骤 4:i=2(越界)→ 把右半部分剩余 [43] 全部搬入 temp = [3, 27, 38, 43] 最后把 temp 拷贝回 arr[left..right]

1.4 三个关键观察

  1. 拆分是 O(log n) 层——每层递归深度增加 1
  2. 每层合并是 O(n)——n 个元素都要比较一次
  3. 总复杂度 = O(n) × O(log n) = O(n log n)

2. 完整 Java 实现

importjava.util.Arrays;publicclassMergeSort{/** * 归并排序入口 */publicstaticvoidmergeSort(int[]arr){if(arr==null||arr.length<2){return;}mergeSort(arr,0,arr.length-1);}/** * 递归拆分 */privatestaticvoidmergeSort(int[]arr,intleft,intright){// 递归终止:区间只剩 0 或 1 个元素if(left>=right){return;}// 防溢出写法(不用 (left + right) / 2)intmid=left+(right-left)/2;mergeSort(arr,left,mid);mergeSort(arr,mid+1,right);merge(arr,left,mid,right);}/** * 合并两个有序子数组 arr[left..mid] 和 arr[mid+1..right] */privatestaticvoidmerge(int[]arr,intleft,intmid,intright){// 创建临时数组int[]temp=newint[right-left+1];inti=left,j=mid+1,k=0;// 双指针合并while(i<=mid&&j<
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/20 3:52:23

Python实现SM3国密哈希算法:从原理到代码实战

1. 项目概述&#xff1a;为什么要在Python里实现SM3&#xff1f;如果你接触过密码学或者国内的软件开发&#xff0c;大概率听说过MD5、SHA-256这些哈希算法。它们就像是数据的“指纹生成器”&#xff0c;能把任意长度的信息&#xff08;比如一个文件、一段密码&#xff09;压缩…

作者头像 李华
网站建设 2026/6/20 3:51:41

Java AES-GCM实战:从原理到生产级安全传输实现

1. 项目概述&#xff1a;为什么AES-GCM是当下安全传输的优选方案&#xff1f;在构建需要网络通信的应用时&#xff0c;数据安全是绕不开的坎。你可能用过AES-CBC加个IV&#xff0c;再配个HMAC做完整性校验&#xff0c;感觉已经挺安全了。但说实话&#xff0c;这套组合拳用起来有…

作者头像 李华
网站建设 2026/6/20 3:49:58

Kimi 2.5 Agent Swarm:轻量级任务协作架构解析

1. 这不是一场技术发布会&#xff0c;而是一次架构认知的校准“Kimi 2.5 的 Agent Swarm 架构是不是伪命题&#xff1f;”——这个问题最近在几个技术群和AI工程实践社区里反复出现&#xff0c;提问者里有刚跑通LangChain本地Agent的应届生&#xff0c;也有带团队落地金融智能投…

作者头像 李华
网站建设 2026/6/20 3:37:10

SQL注入漏洞挖掘实战:从原理到手工探测、工具利用与靶场演练

1. 项目概述&#xff1a;从“拼接字符串”到“掌控数据库”如果你在开发一个网站&#xff0c;用户登录时&#xff0c;你可能会写一段类似SELECT * FROM users WHERE username ‘$username’ AND password ‘$password’的SQL语句。如果直接把用户输入的用户名和密码拼接到这个…

作者头像 李华
网站建设 2026/6/20 3:26:46

Axure RP中文汉化终极指南:3分钟免费实现界面本地化

Axure RP中文汉化终极指南&#xff1a;3分钟免费实现界面本地化 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的…

作者头像 李华