二叉树题解——二叉树的中序遍历【LeetCode】颜色标记法

发布于:2025-07-02 ⋅ 阅读:(25) ⋅ 点赞:(0)

颜色标记法 / 模拟递归法

一、算法逻辑(逐步通顺地讲解)

这段代码的目标依然是实现 中序遍历(左 → 根 → 右),但它通过引入“颜色标记”的方式显式管理节点的访问状态。

🌱 初始化

  • 定义两个常量 WHITE = 0(未访问),GRAY = 1(已访问/待处理);

  • 初始化栈,根节点以 WHITE 状态压入;

  • 准备结果列表 res


🔁 栈模拟递归处理

每次从栈中弹出一个 (color, node) 元组:

✅ 如果 node 是空,跳过:

表示该子树为空,不需要处理。


✅ 如果 node 是白色(WHITE),说明它还没有被访问过:

按中序顺序压入相关节点,但要反着压栈(因为栈是“先进后出”):

先右子树 → 再当前节点(标记为灰色)→ 再左子树

这样下一次从栈顶出来的就是左子树,模拟的是:

左 → 根(GRAY)→ 右


✅ 如果 node 是灰色(GRAY),说明它是“中间处理点”:

此时该节点的左子树已经处理过,右子树还没开始——正是访问当前节点值的正确时机,加入结果数组。


🏁 返回结果

所有节点处理完毕后,res 就是按中序顺序排列的节点值列表。


二、核心点总结

这段代码的核心在于:

通过颜色状态模拟递归流程,显式管理“节点处理的阶段”,从而完成中序遍历。

相比传统的栈模拟或统一写法,它具有以下优势:

  • ✅ 清晰区分每个节点的处理阶段(未访问 / 待访问);

  • ✅ 适用于中序 / 前序 / 后序统一写法,仅需调整压栈顺序;

  • ✅ 可用于复杂场景(如前序+后序同时记录、构建表达式树等)。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right

class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        WHITE, GRAY = 0, 1  # 定义颜色常量
        res = []  # 结果列表
        stack = [(WHITE, root)]  # 初始化栈,根节点以 WHITE 状态压入
        while stack:
            color, node = stack.pop()  # 弹出栈顶元素
            if node is None: continue  # 如果节点为空,跳过
            if color == WHITE:
                # 按照中序遍历的顺序,将右子节点、当前节点、左子节点依次压入栈
                stack.append((WHITE, node.right))
                stack.append((GRAY, node))
                stack.append((WHITE, node.left))
            else:
                # 如果节点是 GRAY 状态,输出其值
                res.append(node.val)
        return res

三、时间复杂度分析

  • 每个节点入栈两次(白色一次 + 灰色一次),每次处理耗时 O(1);

  • 总体处理与节点数量线性相关;

时间复杂度:O(n),其中 n 是树的节点数。


四、空间复杂度分析

  • 最坏情况下所有节点都需要压入栈(树退化为链);

  • 所以栈的空间最坏为 O(n),平均为 O(log n)(平衡树);

  • 结果数组也需要 O(n) 空间;

空间复杂度:O(n)(包含结果数组)


网站公告

今日签到

点亮在社区的每一天
去签到