高性能数组归并算法需预分配全局辅助空间并复用,避免递归中反复malloc;小数组(≤8~16)改用插入排序以提升缓存友好性与常数性能。

要写出高性能的数组归并算法,关键不在“写对”,而在“避开低效惯性”——比如反复分配内存、无差别递归小数组、冗余拷贝。真正影响性能的往往是这些细节。
预分配辅助空间,避免递归中 malloc/free
每次递归都 malloc 临时数组,会触发大量系统调用和内存碎片,严重拖慢速度。正确做法是:在最外层一次性分配与原数组等长的辅助数组,全程复用。
- 声明一个全局或传入的
int *temp,大小为n - 所有递归层级的
merge都读写这块内存,不重新申请 - C 语言中可配合
memcpy或指针偏移直接写回原数组,省去中间复制
小数组改用插入排序
当子数组长度 ≤ 8~16 时,插入排序的常数项更小、缓存友好、无需额外空间,实际比归并更快。
- 在递归入口处加判断:
if (right - left + 1 - 满足条件则调用轻量插入排序(仅需内层循环,无函数调用开销)
- 这个阈值可通过简单基准测试确定,通常 10–16 是较优区间
合并时减少数据移动,避免来回拷贝
传统实现常把合并结果先写进临时数组,再整体拷回原数组——等于每层合并做两次内存写入。优化方向是“交替归并”或“就地写回”。
- 若使用双缓冲(主数组 ↔ 辅助数组交替作为输入/输出),可省去最终
memcpy - 更简单有效的方式:合并时直接往
temp写,合并完成后再用memmove或循环批量拷回对应下标段 - 注意:不要在每次比较后都
arr[i] = temp[i],这破坏缓存局部性
下标计算防溢出,边界处理要严谨
看似微小的索引错误会导致越界、死递归或漏元素,尤其在大数组或嵌套深时暴露明显。
- 中点计算统一用
mid = left + (right - left) / 2,防止left + right溢出 - 左右区间严格划分为
[left, mid]和[mid+1, right],确保递归范围持续缩小 - 合并时检查
i 和 <code>j ,而非 <code>i ,避免漏掉 mid 位置元素











