D

当前:LC94 · 二叉树的中序遍历 · 首次出现于 Day 18 · 路径:顶栏「56天打卡」→ 点击 LC 题号 → 逐题动画

LC94 · 中序遍历 · 工程执行实验室

左墙下潜法

中序遍历的本质是:每个节点都要等左子树处理完,才轮到自己。用 cur、stack、ans 三件套把访问时机讲清楚,而不是只背「左-根-右」。

输出:[1, 2, 3, 4, 5, 6]

核心 · 左墙下潜法

中序遍历的本质是:每个节点都要等左子树处理完,才轮到自己。

  • · 一个节点不是看到就输出。
  • · 必须先完成它的左子树。
  • · 左子树完成后,才访问当前节点。
  • · 当前节点访问后,才进入右子树。
迭代三件套

cur 是当前工作指针;stack 保存「左子树还没处理完」的节点;ans 是已输出序列。 内层循环一路向左压栈,外层弹栈访问后 cur 转向右子树。

递归其实也有栈,只是系统帮你藏起来了
  1. 1.递归代码里的 dfs(root.left) 会暂停当前函数,暂停状态保存在调用栈里。
  2. 2.等左子树返回后,才执行 ans.append(root.val),再进入右子树。
  3. 3.迭代版只是把系统隐藏的调用栈,改成了我们自己维护的 stack。
1/13 · 题目区
关键步:
Step 0题目区

题目:中序遍历示例树,输出 [1,2,3,4,5,6]

给定二叉树:根 4,左子树 2-1-3,右子树 6-5。中序遍历不是背「左-根-右」口诀,而是弄清每个节点何时才能被访问。

为什么

访问时机比顺序口诀更重要:左子树未完成时,根节点不能输出。

状态表 · cur / stack / ans

curstack(栈顶在右)ans动作原因
cur = 4(节点 4)[][]读题目标序列 [1,2,3,4,5,6]
cur 高亮·已访问·等待(描边)
4cur26135stack(栈顶 →)[]ans123456[]
Go · 递归版(直觉入口)
1func inorderTraversal(root *TreeNode) []int {
2 ans := []int{}
3
4 var dfs func(*TreeNode)
5 dfs = func(node *TreeNode) {
6 if node == nil {
7 return
8 }
9
10 dfs(node.Left)
11 ans = append(ans, node.Val)
12 dfs(node.Right)
13 }
14
15 dfs(root)
16 return ans
17}
展开迭代版(面试重点)
func inorderTraversal(root *TreeNode) []int {
    ans := []int{}
    stack := []*TreeNode{}
    cur := root

    for cur != nil || len(stack) > 0 {
        for cur != nil {
            stack = append(stack, cur)
            cur = cur.Left
        }

        cur = stack[len(stack)-1]
        stack = stack[:len(stack)-1]

        ans = append(ans, cur.Val)
        cur = cur.Right
    }

    return ans
}
复杂度
时间
O(n)
空间
O(h)

每个节点最多入栈一次、出栈一次、访问一次,总共 O(n)。

h 为树高;最坏退化链表时 O(n)。递归版用系统调用栈,迭代版用显式 stack。

Morris 遍历可以做到额外空间 O(1),但本页主线不讲 Morris。

面试回答

中序遍历的顺序是左子树、根节点、右子树。递归写法最直观:先 dfs(left),再访问当前节点,再 dfs(right)。迭代写法用显式栈模拟递归调用栈:先一路向左,把经过的节点压栈;当左边走到底后,弹出栈顶访问;然后转向它的右子树。每个节点最多入栈出栈一次,所以时间 O(n),栈空间 O(h),最坏 O(n)。

常见误区
误区 1:看到节点就输出

中序不是「路过就打印」。必须先完成左子树,才轮到自己。

误区 2:弹栈后忘记 cur = cur.Right

访问当前节点后,下一步必须进入右子树,否则右子树会被漏掉。

误区 3:以为中序遍历一定有序

只有二叉搜索树 BST 的中序遍历才天然递增;普通二叉树只是按左-根-右顺序输出。

误区 4:空间复杂度写成 O(1)

递归/显式栈版本是 O(h),最坏退化链表时 O(n),不是 O(1)。