对长度为 n 的数组 arr,调用 `merge_sort(a, 0, n-1)`,在排序过程中,`merge` 函数的递归调用次数大约是多少?

归并排序(Merge Sort) 的标准 基于C++ 实现:

对长度为 n 的数组 arr,调用 merge_sort(a, 0, n-1),在排序过程中,merge 函数的递归调用次数大约是多少?


✅ 一、代码结构回顾

关键递归函数:

void merge_sort(int arr[], int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;
        merge_sort(arr, left, mid);
        merge_sort(arr, mid + 1, right);
        merge(arr, left, mid, right);
    }
}

即每次:

  • 把数组分成两半;
  • 对左右部分分别递归排序;
  • 调用一次 merge() 进行合并。

✅ 二、递归次数分析

对于长度为 n 的数组:

  • 递归深度为 log₂(n) 层;
  • 每一层中会有若干次 merge() 调用。

具体来看:

层级 子数组数 每层 merge 调用次数 总元素个数
第 0 层 1 1 n
第 1 层 2 2 n
第 2 层 4 4 n
第 log₂(n) 层 n/2 n/2 n

✅ 三、merge 调用总次数

  • 每次 merge_sort 会调用一次 merge()
  • 对于 n 个元素,递归树共有 n 个叶子节点(每个元素单独为一部分);
  • 每个非叶子节点对应一次 merge() 调用。

二叉树的非叶节点数约为 n - 1,即:

[
\text{merge 调用次数} \approx n - 1 = O(n)
]


✅ 四、时间复杂度对比(加深理解)

  • 单次 merge 操作: O(n)
  • merge 调用次数: O(n)
  • 递归层数: O(log n)

总体时间复杂度:
[
T(n) = 2T(n/2) + O(n) = O(n \log n)
]


✅ 五、正确答案

在排序过程中,merge 函数的递归调用次数约为:

B. O(n)


✅ 附加总结

项目 复杂度
merge 函数调用次数 O(n)
每次 merge 时间 O(n)
总时间复杂度 O(n log n)
空间复杂度 O(n)

👉 结论:

merge 函数被调用约 O(n) 次,但整个排序的时间复杂度是 O(n log n)。

posted @ 2025-11-09 20:36  kkman2000  阅读(28)  评论(0)    收藏  举报