算法学习—归并排序
本文最后更新于 2025年2月22日 下午
归并排序是分治思想的运用
🤯基本思想:分治之美
将待排序元素分成大小大致相同的2个子集合,分别对2个子集合进行排序,最终将排好序的子集合合并成为所要求的排好序的集合。
归并排序(Merge Sort) 是分治思想的经典应用。其核心理念是:
-
分解:将复杂的大问题分割成简单的小问题
-
解决:逐步解决小问题
-
合并:将解决后的小问题结果组合成最终解
💡 核心口诀:分、治、合!
💻核心算法
✂️分治流程:
-
分割阶段:将待排序数组递归地分成两个大小近似的子数组
-
排序阶段:分别对这两个子数组进行排序
-
合并阶段:将已排序的子数组合并成一个有序数组
1 |
|
📽️过程演示

⌛分步实现
-
确定分界点
1 |
|
-
归并排序每次都是分成大致相同的两部分,所以分界点是 处。
💡 小技巧:使用右移运算符
>>
代替除法,计算更高效
-
递归处理子问题
1 |
|
-
分治法都是通过递归处理子问题。
💡 递归精髓:将大问题不断拆分,直到问题足够小(通常是1-2个元素)
-
合并子问题
1 |
|
💡 合并技巧:总是选择两个子数组中最小的元素
经过步骤2对左右区间进行递归处理后,左右两个子区间都是有序的,这里通过两个指针
i
和j
分别遍历左右子区间,比较当前元素大小,把较小的元素依次放入临时数组temp
。最后,把左右子区间剩余的元素也都放入temp。故扫尾
时直接将剩余的元素加到中间数组后
1 |
|
注意:这里复制的赋值是从递归的起始位置
l
开始的,因为每次排序只是针对l
到r
这个范围的区间进行的
⌨️完整代码
1 |
|
🚀 性能分析
-
时间复杂度
最好/平均/最坏:稳定且高效的排序算法
-
空间复杂度
:需要额外的临时数组空间
❓常见问题
-
内存溢出
如果数据量非常大,可能会因为临时数组占用太多内存导致内存溢出。解决办法可以考虑使用外部排序,或者优化临时数组的使用,比如复用临时数组。 -
小数组性能
在处理小数组时,归并排序的递归开销可能会使性能不如一些简单的排序算法,比如插入排序。可以在小数组时切换到插入排序来提高性能。
💡优化建议
-
减少递归深度
在数据量较小时,使用迭代的方式代替递归,减少栈空间的使用。 -
优化合并操作
在合并时,可以提前判断是否左半部分已经全部小于右半部分,如果是,就可以直接跳过合并操作,提高效率。