树与二叉树
树(Tree)是一种非线性数据结构,用「节点 + 父子关系」描述层级结构,如文件系统目录、HTML 的 DOM、组织架构。二叉树是最简单也最常考的形态,是堆、二叉搜索树、平衡树、B+ 树的共同基础,面试题量占比很高。
树的术语
树由根节点向下分叉,常用术语:
- 根节点:没有父节点的顶层节点。
- 叶子节点:没有子节点的节点。
- 父节点 / 子节点 / 兄弟节点:直接相连的上下层节点、同一父节点的孩子。
- 度:一个节点拥有的子树个数;二叉树要求每个节点度 ≤ 2。
- 深度与高度:深度从根往下数,高度从叶子往上数。
根 A
/ | \
B C D A 的度为 3,B、C、D 是 A 的孩子
/ \
E F E、F 是叶子;整棵树的高度为 2
二叉树的特殊形态
二叉树每个节点最多两个子节点,分左子树与右子树,次序不可颠倒。两种常考的特殊形态:
- 满二叉树:除叶子外每个节点都有两个孩子,叶子全在最后一层。
- 完全二叉树:除最后一层外每层都满,最后一层节点从左到右连续——堆就是建在完全二叉树上的。
满二叉树 完全二叉树
1 1
/ \ / \
2 3 2 3
/ \ / \ / \
4 5 6 7 4 5
二叉树的存储
- 顺序存储:用数组按下标存放。若节点下标为 i,则左孩子是 2i+1、右孩子是 2i+2、父节点是 (i-1)/2,适合完全二叉树。
- 链式存储:每个节点包含数据与左右孩子指针,通用性最强,实际最常用:
class Node:
def __init__(self, val):
self.val = val
self.left = None # 左孩子
self.right = None # 右孩子
遍历:前序、中序、后序与层序
递归遍历按「根的位置」命名:前序(根左右)、中序(左根右)、后序(左右根);层序用队列从上到下、从左到右逐层扫描。
def preorder(root): # 前序遍历
if root is None:
return
print(root.val, end=" ") # 1. 访问根
preorder(root.left) # 2. 递归左子树
preorder(root.right) # 3. 递归右子树
# 对满二叉树 1(2(4,5),3(6,7)) 执行 preorder(root):
# 输出:1 2 4 5 3 6 7
记忆点:中序 + 前序(或中序 + 后序)可以唯一重建一棵二叉树,是经典笔试题。
复杂度与面试要点
- 遍历 n 个节点,时间 O(n);递归实现空间 O(h),h 为树高,最坏退化为 O(n)。
- 完全二叉树用数组存储时,节点 i 的孩子下标是 2i+1 与 2i+2。
- 高频题:求最大深度、判断两棵树是否相同、层序遍历、镜像二叉树、验证二叉搜索树。
- 扩展方向:平衡二叉树、红黑树、B 树/B+ 树都是二叉树的进阶变体,先吃透二叉树再往上走。
小结:树用层级关系组织数据,二叉树因结构规整而成为算法题主流;熟记术语、两种特殊形态与四种遍历顺序,二叉树这关就算过了。