LeetCode 94:二叉树的中序遍历(递归与栈的两种解法)

13 阅读3分钟

二叉树遍历是所有树结构题目的基础,其中**中序遍历(Inorder Traversal)**尤为重要。
很多二叉搜索树(BST)相关题目,本质都离不开中序遍历。

这篇笔记将从「是什么」「怎么做」「为什么这样做」三个角度,系统梳理中序遍历的两种经典解法:

  • 递归解法(最直观)
  • 迭代解法(用栈模拟递归)

一、什么是中序遍历?

中序遍历的访问顺序是:

左子树 → 根节点 → 右子树

举个例子:

    2
   / \
  1   3

中序遍历结果为:

[1, 2, 3]

正是从小到大的顺序,这也是为什么 二叉搜索树的中序遍历一定是有序的


二、题目描述(简化版)

给你一棵二叉树 root,请返回它的中序遍历结果。


三、解法一:递归(最直观)

思路分析

递归解法本质就是直接按照中序遍历的定义来写:

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

这是树结构最自然、最容易理解的写法。


完整代码(递归)

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> result = new ArrayList<>();
        helper(root, result);
        return result;
    }

    public void helper(TreeNode root, List<Integer> result) {
        if (root == null) {
            return;
        }
        helper(root.left, result);
        result.add(root.val);
        helper(root.right, result);
    }
}

逐行解释

if (root == null) {
    return;
}

递归终止条件,遇到空节点直接返回。

helper(root.left, result);

先递归处理左子树。

result.add(root.val);

左子树处理完之后,再访问当前节点。

helper(root.right, result);

最后递归处理右子树。


递归的优缺点

优点:

  • 代码简洁
  • 逻辑清晰
  • 非常符合中序遍历的定义

缺点:

  • 依赖系统递归栈
  • 在极端情况下(树退化成链表)可能栈溢出

四、解法二:迭代(用栈模拟递归)

递归虽然好理解,但面试和工程中经常会要求写非递归版本

那问题来了:
递归是怎么实现中序遍历的?

答案是:靠函数调用栈

所以,非递归版本的核心思想就是:
用一个显式的栈,去模拟递归过程


核心思路

  1. 一路向左,把节点不断压栈
  2. 左子树走到底后,弹出栈顶节点访问
  3. 再转向右子树
  4. 重复上述过程

完整代码(迭代 + 栈)

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()) {
            if (cur != null) {
                stack.push(cur);
                cur = cur.left;
            } else {
                cur = stack.pop();
                result.add(cur.val);
                cur = cur.right;
            }
        }

        return result;
    }
}

逐步执行过程说明

假设当前节点是 cur

  1. 只要 cur 不为空,就一直往左走,并压栈
  2. cur 为空,说明左子树走到头了
  3. 从栈中弹出一个节点,访问它
  4. 然后转向它的右子树

这个过程和递归的执行顺序是完全一致的。


五、递归 vs 迭代,对比总结

维度递归迭代(栈)
思路直观稍微抽象
代码量略多
栈来源系统调用栈手动维护栈
面试友好度

实际刷题建议:

  • 初学阶段:优先写递归,理解遍历本质
  • 熟练之后:必须掌握栈实现,这是高频考点