Chap5 二叉树
返回:0300 数据结构总目录 · 上一章:0304 Chap4 栈与队列 · 下一章:0306 Chap6 图
1、学习目标
树把线性结构扩展成层次结构。二叉树是后续搜索树、堆、Huffman 编码和表达式树的基础。本章要抓住两条线:一是树的结构表示,二是遍历如何把递归结构转成线性序列。
| 模块 | 要掌握的内容 |
|---|---|
| 树基础 | 根、父子、兄弟、祖先、深度、高度、度 |
| 表示 | 父亲表示法、孩子表示法、长子兄弟表示法 |
| 二叉树 | 真二叉树、节点类、树类、高度维护 |
| 遍历 | 先序、中序、后序、层次遍历 |
| 重构 | 由遍历序列恢复二叉树 |
| 应用 | PFC、Huffman 编码 |
2、资料范围
| PDF 课件 | 内容 |
|---|---|
05.Binary_Tree.A.Tree.pdf |
树的概念 |
05.Binary_Tree.B.Representation.pdf |
树的表示 |
05.Binary_Tree.C.Binary_Tree.pdf |
二叉树 |
05.Binary_Tree.D.Implementation.pdf |
BinNode、BinTree 实现 |
05.Binary_Tree.E1-E5 |
先序、中序、后序、层次遍历和重构 |
05.Binary_Tree.F.PFC.pdf |
前缀无歧义编码 |
05.Binary_Tree.G.Huffman.pdf |
Huffman 树 |
3、树的基本概念
| 概念 | 说明 |
|---|---|
| 根 | 没有父节点的节点 |
| 叶子 | 没有孩子的节点 |
| 深度 | 从根到该节点的边数 |
| 高度 | 从该节点到最深叶子的边数 |
| 度 | 节点孩子数量 |
| 子树 | 某节点及其后代形成的树 |
二叉树中,每个节点最多有两个孩子,分别称为左孩子和右孩子。
真二叉树是每个内部节点都有两个孩子的二叉树。很多编码树和表达式树常被扩充成真二叉树,便于统一处理。
4、树的表示
| 表示法 | 思路 | 特点 |
|---|---|---|
| 父亲表示法 | 每个节点记录父节点位置 | 找父亲快,找孩子慢 |
| 孩子表示法 | 每个节点维护孩子列表 | 找孩子快,空间和实现较复杂 |
| 长子兄弟表示法 | 每个节点只记录第一个孩子和下一个兄弟 | 任意树可转二叉树 |
长子兄弟表示法非常重要:
1 | firstChild 表示左孩子 |
它把多叉树统一转化为二叉树,为树结构的通用实现提供入口。
5、二叉树节点
典型节点字段:
1 | template <typename T> |
高度更新:
1 | int stature(BinNode<T>* x) { |
插入节点后,要从插入位置向祖先逐层更新高度。
6、遍历
6.1 先序遍历
顺序:根、左、右。
1 | void preorder(Node* x) { |
迭代版本可用栈,先压右孩子再压左孩子。
6.2 中序遍历
顺序:左、根、右。
1 | void inorder(Node* x) { |
中序遍历对 BST 极其重要:BST 的中序序列是非降序列。
6.3 后序遍历
顺序:左、右、根。后序适合释放树、计算子树信息。
1 | void postorder(Node* x) { |
6.4 层次遍历
层次遍历用队列:
1 | queue<Node*> q; |
7、遍历序列重构
常见结论:
| 已知序列 | 能否唯一重构 |
|---|---|
| 先序 + 中序 | 能 |
| 后序 + 中序 | 能 |
| 先序 + 后序 | 通常不能,除非有额外条件 |
| 层序 + 中序 | 能 |
先序 + 中序重构思路:
- 先序第一个元素是根。
- 在中序中找到根,左边是左子树,右边是右子树。
- 根据左右子树规模切分先序序列。
- 递归构造左右子树。
8、PFC 与 Huffman 编码
PFC 是前缀无歧义编码:任意字符编码都不是另一个字符编码的前缀。这样解码时从左往右读,不会产生歧义。
Huffman 编码构造:
1 | 每次选权重最小的两棵树合并,新树权重为二者之和,直到只剩一棵树。 |
优点:
- 高频字符路径短。
- 低频字符路径长。
- 在给定频率下得到最优前缀编码。
可用优先级队列实现,每次取出两个最小权重节点,复杂度 O(n log n)。
9、复杂度汇总
| 操作 | 复杂度 |
|---|---|
| 遍历整棵树 | O(n) |
| 查找某节点高度 | 若已维护字段 O(1) |
| 插入后更新高度 | O(h) |
| Huffman 建树 | O(n log n) |
10、易错点
| 易错点 | 修正 |
|---|---|
| 混淆深度和高度 | 深度从根往下,高度从节点往叶子 |
| 中序遍历能单独重构树 | 不能,必须配合其他序列 |
| 后序只会递归写法 | 后序迭代需要更细地维护访问状态 |
| 忘记更新祖先高度 | 插入、删除和旋转后都要维护高度 |
| Huffman 只按字符排序 | 关键是频率或权重,不是字符值 |
11、复盘清单
| 检查项 | 状态 |
|---|---|
| 能解释长子兄弟表示法 | 待复盘 |
| 能写出四种遍历框架 | 待复盘 |
| 能用先序和中序重构二叉树 | 待复盘 |
| 能说明 BST 中序有序的原因 | 待复盘 |
| 能手动构造 Huffman 树 | 待复盘 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ruiqy~!







