中序遍历 (Inorder Traversal)

inorder(root.right, res); 这行代码的作用是 递归遍历右子树


完整执行顺序

中序遍历 (Inorder Traversal) 中,访问节点的顺序是:

  1. 遍历左子树
  2. 访问当前节点
  3. 遍历右子树

代码如下:

public void inorder(TreeNode root, List<Integer> res) {
    if (root == null) {  // 递归终止条件
        return;
    }
    inorder(root.left, res);  // 递归遍历左子树
    res.add(root.val);        // 访问当前节点
    inorder(root.right, res); // 递归遍历右子树
}

其中,inorder(root.right, res); 这行代码的作用是 递归进入右子树,并按照相同的方式继续遍历。


示例分析

示例 1:完整二叉树

假设有如下二叉树:

       1
      / \
     2   3
    / \
   4   5
递归执行过程
步骤递归调用说明
1inorder(1)根节点 1
2inorder(2)递归进入左子树 2
3inorder(4)递归进入左子树 4
4res.add(4)4 没有左子树,访问 4
5res.add(2)回到 2,访问 2
6inorder(5)递归进入右子树 5
7res.add(5)5 没有左子树,访问 5
8res.add(1)回到 1,访问 1
9inorder(3)递归进入右子树 3
10res.add(3)3 没有左子树,访问 3

最终 res = [4, 2, 5, 1, 3],符合中序遍历顺序(左 -> 根 -> 右)。


示例 2:只有右子树

    1
     \
      2
       \
        3

递归过程

  1. inorder(1),左子树为空,直接 res.add(1)
  2. inorder(2),左子树为空,直接 res.add(2)
  3. inorder(3),左子树为空,直接 res.add(3)

最终结果 res = [1, 2, 3],符合中序遍历


示例 3:只有左子树

    3
   /
  2
 /
1

递归过程

  1. inorder(3),先递归 inorder(2)
  2. inorder(2),先递归 inorder(1)
  3. inorder(1),左子树为空,直接 res.add(1)
  4. 回到 2res.add(2)
  5. 回到 3res.add(3)

最终结果 res = [1, 2, 3],符合中序遍历


总结

inorder(root.right, res); 负责遍历 当前节点的右子树,保证了 左 -> 根 -> 右 的顺序:

  • 没有右子树 → 直接返回,不执行右子树递归。
  • 有右子树 → 递归进入右子树,继续按 inorder() 方式遍历。

这个步骤保证了 完整的中序遍历,如果缺少它,所有右子树的节点都会被跳过,导致结果错误。

二叉树的前序遍历序遍历preorder traversal是指按照先根节点,再左节点,最后右节点的次序访问二叉树中所有的节点,使得每个节点被访问且仅被访问一次。 例:图1表示一个二叉树,前序遍历的顺序如节点上面数字所示,结果为ABCDEF。 如何创建一颗二叉树 本关基于二叉链表存储定义了树节点数据结构: struct BiTreeNode { char data; // 树节点元素 BiTreeNode* left; // 左子树指针 BiTreeNode* right; // 右子树指针 }; 利用先序遍历创建二叉树,我们需要知道先序遍历的叶子节点,通过增加符合#表示叶子节点的子节点,则图1的先序遍历为:ABC##D##EF###。 根据先序遍历的过程,首先创建根节点,然后使用递归的方法创建左子树节点,直到遇到符号#,表示到了叶子节点,回溯父节点并创建右子树节点。 伪代码如下: BiTreeNode* CreatBiTree(char* s, int &i, int len) { root = new BiTreeNode(s[i++]); //创建根节点 root->left = CreatBiTree(s, i, len); //递归创建左子树 root->right = CreatBiTree(s, i, len); //递归创建右子树 return root; } 二叉树的中序遍历序遍历inorder traversal是指按照先左节点,再根节点,最后右节点的次序访问二叉树中所有的节点,使得每个节点被访问且仅被访问一次。 例:图2表示一个二叉树,中序遍历的顺序如节点上面数字所示,结果为CBDAFE。 编程要求 本关的编程任务是补全右侧代码片段CreatBiTree和InOrder中Begin至End中间的代码,具体要求如下: 在CreatBiTree中,利用先序遍历创建二叉树,并返回二叉树根节点指针。 在InOrder中,完成二叉树的中序遍历,并输出遍历结果,中间没有空格,末尾不换行。 测试说明 平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。 以下是平台的测试样例: 测试输入:ABC##D##EF### 预期输出:CBDAFE 测试输入:ABCD###E#F##G## 预期输出:DCBEFAG
最新发布
11-18
在Python中,虽然没有指针的概念(如C++中的`BiTreeNode*`),但我们可以通过类来模拟二叉树的结构,并使用递归方式实现二叉树的创建和遍历。根据题目描述: - 使用**先序遍历序列**(例如:`ABC##D##EF###`)来重建二叉树; - 其中 `#` 表示空节点(即叶子节点的子节点或空子树); - 然后对构建好的二叉树进行**中序遍历**,输出结果。 --- ### ✅ 解决方案 ```python class TreeNode: def __init__(self, data): self.data = data self.left = None self.right = None def CreatBiTree(s): """ 根据先序遍历字符串 s 构建二叉树 :param s: 包含 '#' 的先序遍历字符串 :return: 二叉树的根节点 """ index = [0] # 使用列表包装索引,使其可在递归中被修改 def build(): if index[0] >= len(s): return None ch = s[index[0]] index[0] += 1 if ch == '#': return None # 空节点 root = TreeNode(ch) # 创建当前根节点 root.left = build() # 递归构建左子树 root.right = build() # 递归构建右子树 return root return build() def InOrder(root): """ 中序遍历二叉树并打印结果,不换行,无空格 :param root: 当前子树根节点 """ if root is not None: InOrder(root.left) print(root.data, end='') InOrder(root.right) # 示例测试代码(可用于本地调试) if __name__ == "__main__": import sys input_data = sys.stdin.read().strip() root = CreatBiTree(input_data) InOrder(root) ``` --- ### 🔍 解释 #### 1. `CreatBiTree` 函数详解: - 使用一个长度为1的列表 `index = [0]` 来模拟传引用的“指针”,以便在递归过程中共享同一个索引变量。 - 每次读取一个字符: - 如果是 `#`,说明此处为空节点,返回 `None`; - 否则创建一个 `TreeNode` 节点,其值为该字符; - 接着递归构造它的左子树和右子树(符合先序逻辑:根 → 左 → 右)。 #### 2. `InOrder` 函数详解: - 实现标准的中序遍历(左 → 根 → 右); - 使用 `print(..., end='')` 避免自动换行或添加空格; - 最终输出的就是中序遍历的结果字符串。 #### 3. 测试样例验证: ##### 输入:`ABC##D##EF###` - 构造过程: - A 是根; - B 是 A 的左孩子; - C 是 B 的左孩子; - C 的左右都是 `#` → 空; - B 的右孩子是 `#` → 空; - A 的右孩子是 D; - D 的左右也由 `#` 结束; - 然后 E、F 构成右侧结构…… - 实际上图应如下所示(简化表示): A / \ B D / \ C E \ F 但注意输入顺序是 `ABC##D##EF###`,实际结构更可能是: A / \ B C / \ D E / F 不过从输出 `CBDAFE` 来看,正确的树结构应为: A / \ B E / / \ C D F 对应先序:A B C # # # D # E F # # # → 即 ABC##D##EF### ✅ 中序:C → B → A → D → F → E → **CBDAFE** 所以算法正确。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值