Skip to main content

核心认知

二叉树不是线性结构,而是层级结构。 它最重要的特点是:每个节点最多只有两个孩子。 这会自然引出两种思维方式:
  • 遍历
  • 递归
所以很多人真正理解递归,往往就是从二叉树开始的。

二叉树节点长什么样

最基础的节点一般包含三个字段:
  • 当前值
  • 左孩子
  • 右孩子
class TreeNode:
    def __init__(
        self,
        val: int = 0,
        left: "TreeNode | None" = None,
        right: "TreeNode | None" = None,
    ):
        self.val = val
        self.left = left
        self.right = right
理解这个结构后,很多题就可以归结成一句话: “当前节点要做什么,左右子树要做什么?”

为什么二叉树题适合递归

因为二叉树天然具备相同子结构。 如果你能处理一棵树,你通常也能用同样的方法处理它的左子树和右子树。所以递归函数通常只需要想清楚三件事:
  1. 参数是什么
  2. 返回值是什么
  3. 单层逻辑是什么

最基础的遍历

二叉树最经典的内容是遍历。 深度优先遍历有三种:
  • 前序遍历
  • 中序遍历
  • 后序遍历
再加上一种广度优先:
  • 层序遍历
区别其实只有一个:什么时候处理当前节点。

一个最经典的 Python 例子

前序遍历是最容易帮助你建立递归直觉的例子。
class TreeNode:
    def __init__(
        self,
        val: int = 0,
        left: "TreeNode | None" = None,
        right: "TreeNode | None" = None,
    ):
        self.val = val
        self.left = left
        self.right = right


def preorder(root: TreeNode | None) -> list[int]:
    result: list[int] = []

    def dfs(node: TreeNode | None) -> None:
        if not node:
            return
        result.append(node.val)
        dfs(node.left)
        dfs(node.right)

    dfs(root)
    return result
这个例子很适合作为二叉树题的起点,因为它同时体现了:
  • 递归终止条件
  • 当前节点处理
  • 左右子树递归

常见题型

二叉树题通常会围绕这些方向展开:
  • 遍历类
  • 深度和高度
  • 路径问题
  • 构造问题
  • 二叉搜索树
  • 最近公共祖先
你真正要做的不是死记题目,而是先判断:这题本质是在考遍历,还是在考递归定义。

二叉树和二叉搜索树的区别

二叉树只要求结构。 二叉搜索树则还要求数值关系:
  • 左子树都比根小
  • 右子树都比根大
这个额外性质会让查找、插入、删除更有规律,也会带来一批专门题型。

学习建议

如果你刚开始刷二叉树,建议按这个顺序来:
  • 前中后序遍历
  • 层序遍历
  • 最大深度
  • 翻转二叉树
  • 路径总和
  • 二叉搜索树基础题
当你习惯先问“递归函数定义是什么”时,二叉树题会清晰很多。