归并排序是分治算法的典型实现,需严格按中点二分(闭区间[left, right])、递归终止于left≥right、中点用left+(right-left)/2防溢出;合并时用辅助数组和双指针,避免覆盖;可优化小数组改插入排序、提前终止等。

归并排序本身就是分治算法的典型实现,关键不在“怎么用”,而在于如何把分治三步——分解、求解、合并——真正落地为清晰、健壮、可优化的 Java 代码。
明确分治结构:递归拆分到单元素
归并排序的分解不是随意切分,而是严格按中点二分,且必须保证区间闭合、边界不越界。常用写法是传入 left 和 right 索引(闭区间),递归终止条件为 left >= right(即子数组长度 ≤1)。
- 中点计算推荐用 int mid = left + (right - left) / 2,避免大整数溢出
- 左右子区间分别是 [left, mid] 和 [mid+1, right],注意右半段起始不能错写成 mid
- 递归调用顺序无关性能,但逻辑上应先完成左右子数组各自排序,再合并
合并操作:双指针 + 辅助数组,避免覆盖
合并的本质是将两个已有序的子数组([left, mid] 和 [mid+1, right])合并回原数组对应位置。必须借助临时数组,否则原数据会被提前覆盖。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 临时数组只需覆盖当前合并区间,长度为 right - left + 1,不要每次 new 全局大小
- 复制时用 System.arraycopy(arr, left, aux, 0, aux.length) 比循环更高效
- 双指针 i(左段起点)、j(右段起点)、k(原数组写入位置),判断逻辑要覆盖三种情况:左段耗尽、右段耗尽、正常比较
常见优化点:提升实际运行效率
理论 O(n log n) 很漂亮,但常数因子影响真实表现。几个实用优化可显著提速:
- 小数组改用插入排序:当子数组长度 ≤16(经验值),直接插入排序比递归归并更快,跳过分治开销
- 提前终止合并:若 aux[mid - left] ,说明左右已天然有序,无需合并
- 复用辅助数组:在顶层方法中一次性分配足够大的 aux 数组,递归中只传引用,避免重复 new/gc
泛型与自定义顺序:让排序更通用
原生 int[] 排序只是特例。用泛型 + Comparator 能适配任意对象,且保持稳定性和可扩展性。
- 方法签名示例:
void mergeSort(T[] arr, Comparator cmp) - 合并时比较用 cmp.compare(aux[i], aux[j]) ,而非 运算符
- 注意泛型数组创建限制,辅助数组需声明为 Object[] 并安全转型
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










