当前位置: 首页 > news >正文

二叉树的中序遍历 递归调用的完整展开

层序遍历为 1 2 3 4 5 6 7 的二叉树,其中序遍历的递归调用的过程实际上是什么样的?

// 中序遍历
const inorder = (root) => {if (!root) {return;}inorder(root.left);res.push(root.val);inorder(root.right);}

递归调用的完整展开

为了更清晰地看到所有执行的语句,我们可以将所有递归调用展开:

inorder(1):if (!1)falseinorder(1.left)inorder(2):if (!2)falseinorder(2.left)inorder(4):if (!4)falseinorder(4.left)inorder(null):if (!null)returnres.push(4)inorder(4.right)inorder(null):if (!null)returnres.push(2)inorder(2.right)inorder(5):if (!5)falseinorder(5.left)inorder(null):if (!null)returnres.push(5)inorder(5.right)inorder(null):if (!null)returnres.push(1)inorder(1.right)inorder(3):if (!3)falseinorder(3.left)inorder(6):if (!6)falseinorder(6.left)inorder(null):if (!null)returnres.push(6)inorder(6.right)inorder(null):if (!null)returnres.push(3)inorder(3.right)inorder(7):if (!7)falseinorder(7.left)inorder(null):if (!null)returnres.push(7)inorder(7.right)inorder(null):if (!null)return

初始理解

首先,我们需要明确几个概念:

  1. 层序遍历:这是指按照树的层次从上到下、从左到右依次访问节点。给定的层序遍历序列是 1 2 3 4 5 6 7,这意味着:

    • 第一层:1(根节点)
    • 第二层:2(左子节点),3(右子节点)
    • 第三层:4(2的左子节点),5(2的右子节点),6(3的左子节点),7(3的右子节点)

    因此,二叉树的结构如下:

        1/ \2   3/ \ / \4  5 6 7
  1. 中序遍历:这是指按照“左子树 - 根节点 - 右子树”的顺序访问节点。对于上面的二叉树,中序遍历的结果应该是 4 2 5 1 6 3 7

  2. 递归过程:给定的中序遍历的递归代码会按照上述顺序访问节点。我们需要将递归调用展开,看看具体的执行顺序。

递归展开

让我们从根节点 1 开始,逐步展开递归调用。我们将 inorder(root) 替换为具体的节点值来表示当前的 root

初始调用:inorder(1)

1. inorder(1)
  • root1,不为 null,所以:
    • inorder(1.left):即 inorder(2)
    • res.push(1.val):即 res.push(1)
    • inorder(1.right):即 inorder(3)
2. inorder(2)
  • root2,不为 null,所以:
    • inorder(2.left):即 inorder(4)
    • res.push(2.val):即 res.push(2)
    • inorder(2.right):即 inorder(5)
3. inorder(4)
  • root4,不为 null,所以:
    • inorder(4.left)4.leftnullinorder(null) 直接返回
    • res.push(4.val):即 res.push(4)
    • inorder(4.right)4.rightnullinorder(null) 直接返回
  • 执行顺序:
    • inorder(null)4.left):无操作
    • res.push(4)
    • inorder(null)4.right):无操作
  • inorder(4) 完成
回到 inorder(2)
  • 已经执行了 inorder(4),接下来:
    • res.push(2)
    • inorder(5)
4. inorder(5)
  • root5,不为 null,所以:
    • inorder(5.left)5.leftnullinorder(null) 直接返回
    • res.push(5.val):即 res.push(5)
    • inorder(5.right)5.rightnullinorder(null) 直接返回
  • 执行顺序:
    • inorder(null)5.left):无操作
    • res.push(5)
    • inorder(null)5.right):无操作
  • inorder(5) 完成
回到 inorder(2)
  • 已经执行了 inorder(5)inorder(2) 完成
回到 inorder(1)
  • 已经执行了 inorder(2),接下来:
    • res.push(1)
    • inorder(3)
5. inorder(3)
  • root3,不为 null,所以:
    • inorder(3.left):即 inorder(6)
    • res.push(3.val):即 res.push(3)
    • inorder(3.right):即 inorder(7)
6. inorder(6)
  • root6,不为 null,所以:
    • inorder(6.left)6.leftnullinorder(null) 直接返回
    • res.push(6.val):即 res.push(6)
    • inorder(6.right)6.rightnullinorder(null) 直接返回
  • 执行顺序:
    • inorder(null)6.left):无操作
    • res.push(6)
    • inorder(null)6.right):无操作
  • inorder(6) 完成
回到 inorder(3)
  • 已经执行了 inorder(6),接下来:
    • res.push(3)
    • inorder(7)
7. inorder(7)
  • root7,不为 null,所以:
    • inorder(7.left)7.leftnullinorder(null) 直接返回
    • res.push(7.val):即 res.push(7)
    • inorder(7.right)7.rightnullinorder(null) 直接返回
  • 执行顺序:
    • inorder(null)7.left):无操作
    • res.push(7)
    • inorder(null)7.right):无操作
  • inorder(7) 完成
回到 inorder(3)
  • 已经执行了 inorder(7)inorder(3) 完成
回到 inorder(1)
  • 已经执行了 inorder(3)inorder(1) 完成

执行顺序总结

按照上述展开,res.push 的执行顺序(即中序遍历的顺序)如下:

  1. inorder(4)
    • res.push(4)
  2. inorder(2)
    • res.push(2)
  3. inorder(5)
    • res.push(5)
  4. inorder(1)
    • res.push(1)
  5. inorder(6)
    • res.push(6)
  6. inorder(3)
    • res.push(3)
  7. inorder(7)
    • res.push(7)

因此,res 中的最终顺序是 [4, 2, 5, 1, 6, 3, 7]

实际执行的 res.push 语句顺序

从上面的展开中,提取所有 res.push 的语句:

  1. res.push(4)
  2. res.push(2)
  3. res.push(5)
  4. res.push(1)
  5. res.push(6)
  6. res.push(3)
  7. res.push(7)

验证中序遍历

让我们手动进行中序遍历以验证:

  • 从根节点 1 开始:
    • 遍历左子树 2
      • 遍历 2 的左子树 4
        • 4 无左子节点,访问 4
        • 4 无右子节点
      • 访问 2
      • 遍历 2 的右子树 5
        • 5 无左子节点,访问 5
        • 5 无右子节点
    • 访问 1
    • 遍历右子树 3
      • 遍历 3 的左子树 6
        • 6 无左子节点,访问 6
        • 6 无右子节点
      • 访问 3
      • 遍历 3 的右子树 7
        • 7 无左子节点,访问 7
        • 7 无右子节点

访问顺序:4, 2, 5, 1, 6, 3, 7,与递归展开的结果一致。

最终答案

将所有的递归调用展开后,实际执行的 res.push 语句的顺序如下:

  1. res.push(4)
  2. res.push(2)
  3. res.push(5)
  4. res.push(1)
  5. res.push(6)
  6. res.push(3)
  7. res.push(7)

因此,中序遍历的结果是 [4, 2, 5, 1, 6, 3, 7]

相关文章:

  • 完整卸载 Fabric Manager 的方法
  • Python海龟绘图(Turtle Graphics)核心函数和关键要点
  • W5500使用ioLibrary库创建DHCP客户端
  • 生产者 - 消费者模式实现方法整理
  • python + streamlink 下载 vimeo 短视频
  • 【Element UI】表单及其验证规则详细
  • DAY 23 训练
  • Python 3.11详细安装步骤(包含安装包)Python 3.11详细图文安装教程
  • Python 基础之函数命名
  • Nginx应用场景详解与配置指南
  • 【时时三省】(C语言基础)字符数组应用举例2
  • DeepSeek-R1 Supervised finetuning and reinforcement learning (SFT + RL)
  • MATLAB安装常见问题及解决办法
  • 开源项目实战学习之YOLO11:12.4 ultralytics-models-sam-memory_attention.py源码分析
  • 强化学习中,frames(帧)和 episodes(回合)
  • 重排序模型解读 mxbai-rerank-base-v2 强大的重排序模型
  • 我司助力高校打造「智慧创新AI学习中心」
  • 互联网大厂Java求职面试:AI驱动的短视频直播平台架构设计
  • 软件设计师考试结构型设计模式考点全解析
  • 学习深度学习是否要先学习机器学习?
  • 知名中医讲师邵学军逝世,终年51岁
  • 荣盛发展:新增未支付债务11.05亿元
  • 圆桌丨全球化博弈与人工智能背景下,企业如何落地合规体系
  • 上海:到2027年,实现近海航线及重点海域5G网络高质量覆盖
  • 广西百色“致富果”:高品质芒果直供香港,带动近五千户增收
  • 沃尔玛上财季净利下滑12%:关税带来成本压力,新财季价格涨幅将高于去年