Skip to content

本章目标:掌握二叉树的各种遍历方式与经典递归模式,能解决 BST 和路径类问题。

你将学到

  • 二叉树四种遍历(前序、中序、后序、层序)
  • 递归与迭代两种写法
  • BST 的性质与验证
  • 最近公共祖先(LCA)
  • 路径总和系列
  • 平衡二叉树判断
  • 序列化与反序列化

1. 概念

树是递归定义的数据结构:一棵树要么为空,要么由根节点和若干子树组成。二叉树每个节点最多有两个子节点。

树的绝大多数问题都可以用递归解决:把问题分解为「左子树的结果 + 右子树的结果 + 当前节点的处理」。掌握树的关键在于写出正确的递归函数,定义清楚「这个函数返回什么」。

二叉搜索树(BST)的特殊性质:中序遍历得到递增序列。这一性质在验证 BST、找前驱后继、第 K 小等问题中反复使用。

2. 核心模板

二叉树定义

swift
public class TreeNode {
    public var val: Int
    public var left: TreeNode?
    public var right: TreeNode?
    public init(_ val: Int) { self.val = val }
}

中序遍历(迭代)

swift
func inorderTraversal(_ root: TreeNode?) -> [Int] {
    var result: [Int] = []
    var stack: [TreeNode] = []
    var curr = root
    while curr != nil || !stack.isEmpty {
        while let node = curr {
            stack.append(node)
            curr = node.left
        }
        curr = stack.removeLast()
        result.append(curr!.val)
        curr = curr!.right
    }
    return result
}

层序遍历(BFS)

swift
func levelOrder(_ root: TreeNode?) -> [[Int]] {
    guard let root = root else { return [] }
    var result: [[Int]] = []
    var queue: [TreeNode] = [root]
    while !queue.isEmpty {
        let count = queue.count
        var level: [Int] = []
        for _ in 0..<count {
            let node = queue.removeFirst()
            level.append(node.val)
            if let left = node.left { queue.append(left) }
            if let right = node.right { queue.append(right) }
        }
        result.append(level)
    }
    return result
}

复杂度

  • 所有遍历:时间 O(n),空间 O(h),h 为树高,最坏 O(n)

3. 经典题目精讲

LeetCode 104 · 二叉树最大深度

题意:求二叉树最大深度。

思路:经典递归——当前深度 = 1 + max(左子树深度, 右子树深度)。

swift
func maxDepth(_ root: TreeNode?) -> Int {
    guard let root = root else { return 0 }
    return 1 + max(maxDepth(root.left), maxDepth(root.right))
}

LeetCode 236 · 最近公共祖先

题意:找两个节点 p 和 q 在二叉树中的最近公共祖先。

思路:递归——如果当前节点是 p 或 q,返回它;左右子树各找一次,两边都找到说明当前节点就是 LCA。

swift
func lowestCommonAncestor(_ root: TreeNode?, _ p: TreeNode?, _ q: TreeNode?) -> TreeNode? {
    guard let root = root else { return nil }
    if root === p || root === q { return root }
    let left = lowestCommonAncestor(root.left, p, q)
    let right = lowestCommonAncestor(root.right, p, q)
    if left != nil && right != nil { return root }
    return left ?? right
}

LeetCode 110 · 平衡二叉树

题意:判断二叉树是否高度平衡(左右子树高度差不超过 1)。

思路:自底向上返回高度,遇到不平衡直接返回 -1 提前终止。

swift
func isBalanced(_ root: TreeNode?) -> Bool {
    return height(root) != -1
}

private func height(_ node: TreeNode?) -> Int {
    guard let node = node else { return 0 }
    let leftH = height(node.left)
    if leftH == -1 { return -1 }
    let rightH = height(node.right)
    if rightH == -1 { return -1 }
    if abs(leftH - rightH) > 1 { return -1 }
    return 1 + max(leftH, rightH)
}

4. 易错点

  • ⚠️ 递归基线(base case)别忘了处理 nil
  • ⚠️ 验证 BST 时不能只比较节点与其直接子节点,需传递上下界
  • ⚠️ Swift 中树节点是引用类型,=== 比较身份
  • ⚠️ 层序遍历记录每层数量后再统一出队,否则层数混乱

5. 推荐刷题清单

题号题名难度关键
94中序遍历Easy迭代遍历
102层序遍历MediumBFS
104二叉树最大深度Easy递归
110平衡二叉树Easy自底向上
226翻转二叉树Easy递归交换
236最近公共祖先Medium递归
297序列化二叉树Hard前序/层序

延伸阅读

基于 VitePress 构建 · 部署于 Cloudflare Pages