You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于归并排序递归逻辑及merge方法作用的技术问询

归并排序递归逻辑与merge方法详解——以int[] intArr = {16, 12, 9, 3, 19}为例

首先得纠正你一个关键误解:merge方法从来不会处理两个未排序的子数组。归并排序的核心是「分而治之」——先通过递归把数组拆到最小单元(单个元素,天然有序),再逐层把有序的子数组合并起来,最终得到整个有序数组。咱们结合你给的sort代码和示例数组,一步步拆解执行过程,你就能明白merge的作用和递归的流程了。

先明确你提供的sort代码(这里默认intArr是全局数组):

public static int[] sort(int l, int r) { 
    if (l < r) { 
        int q = (l + r) / 2; 
        sort(l, q);          // 递归处理左半部分
        sort(q + 1, r);      // 递归处理右半部分
        merge(l, q, r);      // 合并两个已排序的子数组
    } 
    return intArr; 
}

示例数组的递归执行全流程

咱们以intArr = {16, 12, 9, 3, 19}为例,初始调用是sort(0, 4)(数组索引从0到4,共5个元素):

第一步:拆分左半部分直到最小单元

  1. 调用sort(0,4):

    • l=0 < r=4,计算中间索引q=(0+4)/2=2
    • 先执行sort(0,2)(对应左半部分元素{16,12,9}),此时sort(0,4)暂停执行,进入下一层递归。
  2. 调用sort(0,2):

    • l=0 < r=2,计算q=(0+2)/2=1
    • 先执行sort(0,1)(对应元素{16,12}),sort(0,2)暂停。
  3. 调用sort(0,1):

    • l=0 < r=1,计算q=(0+1)/2=0
    • 先执行sort(0,0):l==r,单个元素无需排序,直接返回原数组。
    • 再执行sort(1,1):同样l==r,直接返回。
    • 此时左右子数组都是单个有序元素,执行merge(0,0,1):合并{16}和{12},得到有序的{12,16},原数组变为{12,16,9,3,19}。
    • sort(0,1)执行完毕,回到sort(0,2)。
  4. 回到sort(0,2):

    • 执行sort(2,2):单个元素直接返回。
    • 此时左子数组是{12,16}(已排序),右子数组是{9}(已排序),执行merge(0,1,2):合并后得到{9,12,16},原数组变为{9,12,16,3,19}。
    • sort(0,2)执行完毕,回到sort(0,4)。

第二步:拆分右半部分直到最小单元

回到sort(0,4),现在处理右半部分:

  1. 执行sort(3,4)(对应元素{3,19}):
    • l=3 < r=4,计算q=(3+4)/2=3
    • 执行sort(3,3):直接返回。
    • 执行sort(4,4):直接返回。
    • 执行merge(3,3,4):合并{3}和{19},得到{3,19},原数组保持{9,12,16,3,19}(这部分本来就是有序的,所以无变化)。
    • sort(3,4)执行完毕,回到sort(0,4)。

第三步:合并最终的两个有序子数组

现在sort(0,4)的左右子数组都已经是有序的了:

  • 左子数组:索引0-2,元素{9,12,16}
  • 右子数组:索引3-4,元素{3,19}

执行merge(0,2,4),把这两个有序数组合并成整个有序数组:

  • 临时数组依次放入较小的元素:3 → 9 →12 →16 →19
  • 把临时数组复制回原数组,最终得到{3,9,12,16,19}。

关于merge方法的核心作用

merge方法的唯一职责就是合并两个相邻的、已经有序的子数组,它的输入一定是两个有序区间:

  • 左区间:[l, q](从索引l到q,已排序)
  • 右区间:[q+1, r](从索引q+1到r,已排序)

它的大致执行逻辑是:

  1. 创建临时数组,用来存放合并后的有序结果。
  2. 用两个指针分别指向左右区间的起始位置,循环比较两个指针指向的元素,把较小的元素放入临时数组,并移动对应指针。
  3. 当其中一个区间的元素全部处理完,把另一个区间剩下的元素直接追加到临时数组末尾。
  4. 最后把临时数组的内容复制回原数组的[l, r]区间,完成合并。

所以你之前的疑问“首次迭代时是否会以merge({16,12}, {9,3,19})的形式调用merge”——答案是不会,因为递归会先把左右子数组都拆分成单个元素,合并成有序子数组后,才会触发最终的merge操作。

内容的提问来源于stack exchange,提问作者soulcraft123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 19:29:04