【Leetcode hot 100】94.二叉树的中序遍历
问题链接
94.二叉树的中序遍历
问题描述
给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。
示例 1:
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
提示:
- 树中节点数目在范围
[0, 100]
内 -100 <= Node.val <= 100
问题解答
二叉树的中序遍历顺序为:左子树 → 根节点 → 右子树。以下提供两种常见解法:递归(简单直观)和迭代(进阶要求)。
方法一:递归解法
递归是最直接的实现方式,利用递归栈的特性自然满足中序遍历的顺序。
import java.util.ArrayList;
import java.util.List;class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();// 调用递归辅助方法inorder(root, result);return result;}// 递归辅助函数:遍历当前节点,并将结果存入resultprivate void inorder(TreeNode node, List<Integer> result) {// 边界条件:若节点为空,直接返回if (node == null) {return;}// 1. 先遍历左子树inorder(node.left, result);// 2. 再访问当前节点(根节点)result.add(node.val);// 3. 最后遍历右子树inorder(node.right, result);}
}
思路解析:
- 递归函数
inorder
负责处理单个节点:先递归遍历左子树,再将当前节点的值加入结果列表,最后递归遍历右子树。 - 终止条件:当节点为
null
时,递归结束(空树/叶子节点的子节点无需处理)。
方法二:迭代解法(栈实现)
迭代法通过显式使用栈模拟递归过程,避免递归调用的栈开销,更符合进阶要求。
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;class Solution {public List<Integer> inorderTraversal(TreeNode root) {List<Integer> result = new ArrayList<>();Stack<TreeNode> stack = new Stack<>();TreeNode cur = root; // 指针记录当前遍历的节点// 循环条件:当前节点不为空 或 栈不为空(还有节点未处理)while (cur != null || !stack.isEmpty()) {// 1. 先将所有左子节点入栈(直到最左侧节点)while (cur != null) {stack.push(cur);cur = cur.left; // 移动到左子节点}// 2. 弹出栈顶节点(此时左子树已处理完,该节点为当前子树的根节点)cur = stack.pop();result.add(cur.val); // 加入结果列表(处理根节点)// 3. 处理右子树cur = cur.right;}return result;}
}
思路解析:
- 使用
cur
指针追踪当前节点,先将所有左子节点依次入栈(确保左子树优先处理)。 - 当
cur
为空时,弹出栈顶节点(此时该节点的左子树已处理完),将其值加入结果列表,再将cur
指向其右子节点(处理右子树)。 - 循环直至
cur
为空且栈为空(所有节点处理完毕)。
复杂度分析
- 时间复杂度:两种方法均为
O(n)
,其中n
为二叉树节点数(每个节点恰好被访问一次)。 - 空间复杂度:
- 递归解法:
O(h)
(h
为树的高度,递归栈深度),最坏情况(链状树)为O(n)
。 - 迭代解法:
O(h)
(栈存储的节点数不超过树的高度),最坏情况为O(n)
。
- 递归解法:
两种方法均能正确处理示例输入:
- 示例1:
root = [1,null,2,3]
→ 输出[1,3,2]
- 示例2:
root = []
→ 输出[]
- 示例3:
root = [1]
→ 输出[1]