树与二叉树基础
含AI生成内容
树与二叉树基础
树的定义与基本术语
树的递归定义
树(Tree)是 n(n ≥ 0)个结点的有限集合。当 n = 0 时称为空树;当 n > 0 时,满足以下条件:
- 有且仅有一个称为根(Root)的结点
- 其余结点可分为 m(m > 0)个互不相交的有限集合 T₁, T₂, …, Tₘ,每个集合本身又是一棵树,称为根的子树(Subtree)
这个递归定义是理解树所有操作的基础——树的算法几乎天然适合用递归实现。
基本术语
| 术语 | 定义 | 说明 |
|---|---|---|
| 结点(Node) | 树中的基本数据单元 | 包含数据元素和指向子树的指针 |
| 度(Degree) | 结点拥有的子树个数 | 整个树中最大的结点度称为树的度 |
| 叶子(Leaf) | 度为 0 的结点 | 也称终端结点 |
| 分支结点 | 度 > 0 的结点 | 也称非终端结点、内部结点 |
| 孩子(Child) | 结点的子树的根 | 该结点的直接后继 |
| 双亲(Parent) | 结点的上层结点 | 该结点的直接前驱 |
| 兄弟(Sibling) | 同一双亲的孩子之间 | 互称兄弟 |
| 祖先(Ancestor) | 从根到该结点的路径上所有结点 | 不含自身 |
| 子孙(Descendant) | 该结点子树中的任意结点 | 含自身?不含 |
| 深度(Depth) | 从根到该结点的层数 | 根为第 1 层,向下递增 |
| 高度(Height) | 从该结点到最远叶子经过的边数 | 叶子高度为 0 |
| 层次(Level) | 根为第 1 层 | 深度与层次含义相同 |
注意:考研 408 中,“深度”和”高度”是站在不同角度定义的。深度从根往下数(根为 1),高度从叶子往上数(叶子为 0 或 1)。部分教材将叶子高度定义为 1,做题时以题目说明为准,但 408 统考倾向于高度 = 最大层数。
树的性质
- 树中结点数 = 所有结点的度数之和 + 1
- 度为 m 的树中第 i 层上至多有 m^(i-1) 个结点(i ≥ 1)
- 高度为 h 的 m 叉树至多有 (m^h - 1) / (m - 1) 个结点(满 m 叉树)
- 具有 n 个结点的 m 叉树的最小高度为 ⌈log_m(n(m-1) + 1)⌉
二叉树定义
二叉树(Binary Tree)是 n(n ≥ 0)个结点的有限集合,满足以下条件之一:
- 空树(n = 0)
- 由一个根结点和两个互不相交的子树构成,分别称为左子树和右子树,左右子树本身也是二叉树
二叉树的重要特征
- 每个结点最多有 2 棵子树(度 ≤ 2)
- 左右子树严格区分,顺序不能颠倒
- 二叉树不是度为 2 的有序树的特例——二者的区别在于:二叉树允许结点最多有 2 棵子树(可以为 0 或 1 棵),而度为 2 的有序树要求结点恰好有 2 棵子树(度为 0 或 1 的结点不符合定义)。因此二叉树是比度为 2 的有序树更一般的结构。
特殊二叉树
| 类型 | 定义 | 性质 |
|---|---|---|
| 满二叉树 | 高度为 h,结点数为 2^h - 1 | 所有叶子在同一层,每个结点度均为 0 或 2 |
| 完全二叉树 | 从左到右连续排列,无跳跃 | 叶子只出现在最下两层,n₁ 只可能为 0 或 1 |
| 二叉排序树 | 左 < 根 < 右 | 见 BST 与 AVL |
| 平衡二叉树 | BF | |
| 线索二叉树 | 利用空指针指向前驱后继 | 见 二叉树遍历与线索化 |
二叉树的重要性质
性质一:结点数与度数的关系
n₀ = n₂ + 1 (叶子结点数 = 度为 2 的结点数 + 1)
证明:设 n₀、n₁、n₂ 分别表示度为 0、1、2 的结点数,总结点数 n = n₀ + n₁ + n₂。从边的角度看,每条边对应一个非根结点:边数 = n - 1 = 0·n₀ + 1·n₁ + 2·n₂。联立两式得 n₀ = n₂ + 1。
⚠️ 考研超高频考点:n₀ = n₂ + 1 几乎在每年的 408 真题中出现。可用于:已知叶子结点数求度为 2 的结点数,或反过来求。注意该性质只适用于二叉树。
性质二:完全二叉树的结点数关系
- n₁ 只能为 0 或 1(当总结点数为奇数时 n₁ = 1,偶数时 n₁ = 0)
- 第 i 个结点的双亲编号为 ⌊i/2⌋(i > 1)
- 第 i 个结点的左孩子编号为 2i(2i ≤ n),右孩子编号为 2i+1(2i+1 ≤ n)
性质三:空指针域
具有 n 个结点的二叉树,用二叉链表存储时,空指针域数量为 n + 1。
证明:n 个结点的二叉链表共有 2n 个指针域,但只有 n-1 条边(非空指针),所以空指针数 = 2n - (n-1) = n + 1。这个性质是线索二叉树的基础——线索二叉树正是利用这些空指针存放前驱和后继信息。
二叉树的存储结构
顺序存储
用一维数组按完全二叉树的顺序存放结点:
下标: [1] [2] [3] [4] [5] [6] [7] ...结点: a b c d e f g ...下标规则:
- 结点 i 的左孩子:2i
- 结点 i 的右孩子:2i + 1
- 结点 i 的双亲:⌊i/2⌋
适用场景:完全二叉树和满二叉树。普通二叉树会造成大量空间浪费(需要补充空结点到完全二叉树形式)。
考研关键点:顺序存储的下标从 1 开始更常见,但有些题目可能从 0 开始。从 0 开始时,左孩子为 2i+1,右孩子为 2i+2。
链式存储
二叉链表(最常用):
typedef struct BiTNode { int data; struct BiTNode *lchild, *rchild;} BiTNode, *BiTree; [data] / \ lchild rchild三叉链表(增加 parent 指针,便于回溯):
typedef struct TriTNode { int data; struct TriTNode *lchild, *rchild, *parent;} TriTNode, *TriTree;两种存储结构对比
| 对比项 | 顺序存储 | 链式存储 |
|---|---|---|
| 空间利用 | 完全二叉树好,普通二叉树差 | 较灵活,但有指针开销 |
| 访问孩子 | O(1) 直接下标计算 | O(1) 通过指针 |
| 增删结点 | 困难(需移动大量元素) | 简单(改指针即可) |
| 适用场景 | 完全二叉树(如堆) | 一般二叉树 |
与遍历和工具结构的关系
- 二叉树的遍历算法建立在上述存储结构基础之上,详见 二叉树的遍历与线索化
- 非递归遍历依赖 栈(Stack) 模拟递归过程
- 层序遍历依赖 队列(Queue) 按层次顺序访问结点
- 二叉排序树和平衡二叉树的概念基于二叉树,详见 二叉排序树与平衡二叉树
- 哈夫曼树是带权二叉树的一种最优形态,详见 哈夫曼树
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!










