数据结构第五章:树与二叉树

一、树的基本概念(基础必考)

✅ 树的定义

  • 树(Tree) 是一个非线性结构,由 n(n ≥ 0)个节点组成。
  • 满足:
    • 有且仅有一个根节点
    • 其余节点分为 m(m ≥ 0)个互不相交的子集,每个子集本身也是一棵树(称为子树)

🔑 基本术语

术语 含义
父节点/子节点 直接相连的两个节点中,上为父,下为子
兄弟节点 同一个父节点下的节点
一个节点的子树个数
叶子节点 度为 0 的节点
深度 根到该节点的路径长度(根深度为 0 或 1,视题目而定)
高度 从该节点到最远叶子的距离(叶子高度为 0)

💡 考点:判断树的度、深度、高度;区分"深度"与"高度"


二、二叉树(重中之重!)

✅ 定义与特征

二叉树 是每个节点最多有两个子树的有序树,子树分为左子树右子树

✅ 主要特征:
  1. 左右子树顺序不可交换
  2. 第 i 层最多有 2i−12i−1 个节点
  3. 深度为 k 的二叉树最多有 2k−12k−1 个节点
  4. 任意二叉树中,叶子节点数 = 度为 2 的节点数 + 1

💡 考点:计算最大节点数、叶子节点数、度为 2 的节点数


✅ 存储结构

1. 顺序存储结构
  • 用数组存储完全二叉树
  • 规律:
    • 若根在 arr[0],则:
      • 左孩子:2*i + 1
      • 右孩子:2*i + 2
      • 父亲:(i-1)/2

✅ 优点:节省空间,便于访问

❌ 缺点:只适用于完全二叉树,插入删除效率低

2. 链式存储结构(常用)
cpp 复制代码
typedef struct BiTNode {
	ElemType data; // 数据域
	struct BiTNode *lchild, *rchild; // 左、右孩子指针
} BiTNode, *BiTree;

✅ 二叉树的遍历(核心考点)

类型 顺序 特点
前序遍历 根 → 左 → 右 用于复制树、表达式求值
中序遍历 左 → 根 → 右 二叉搜索树中可得有序序列
后序遍历 左 → 右 → 根 用于删除树、释放内存

💡 考点:手写遍历序列、已知两种遍历还原树、判断是否为二叉搜索树


✅ 线索二叉树(优化遍历)

✅ 问题:
  • 二叉树遍历需要栈或递归,无法直接访问前驱/后继
✅ 解决方案:线索化
  • 利用空指针域存放前驱或后继信息
  • 分为:
    • 前序线索树
    • 中序线索树(最常用)
    • 后序线索树
✅ 中序线索树示例:
  • 若左孩子为空,则指向中序前驱
  • 若右孩子为空,则指向中序后继

💡 考点:理解线索化的思想,能画出中序线索树


三、树与森林

✅ 树的存储结构

1. 双亲表示法
  • 每个节点记录其父节点编号
  • 适合查找父节点
cpp 复制代码
#define MAX_TREE_SIZE 100 // 书中最多结点数

typedef struct { // 树的结点定义
	ElemType data; // 数据元素
	int parent; // 双亲位置域
} PTNode;

typedef struct { // 树的类型定义
	PTNode nodes[MAX_TREE_SIZE]; // 双亲表示
	int n; // 结点数
} PTree;
2. 孩子表示法
  • 每个节点存储其所有孩子
  • 适合查找子树
3. 孩子兄弟表示法(重要!)
  • 每个节点有两个指针:
    • firstchild:指向第一个孩子
    • nextsibling:指向下一个兄弟
  • 优点:可将树转化为二叉树
cpp 复制代码
typedef struct CSNode {
	ElemType data; // 数据域
	struct CSNode *lchild, *nextsibling; // 第一个孩子和兄弟结点
} CSNode, *CSTree;

✅ 森林与二叉树的转换

✅ 核心思想:
  • 将森林中的每棵树按"孩子兄弟表示法"转换为二叉树
  • 多棵树之间通过兄弟关系连接
✅ 转换规则:
  1. 第一棵树:根为新二叉树的根
  2. 后续树:作为前一棵树的右兄弟
  3. 每个节点:左孩子是第一个孩子,右孩子是下一个兄弟

💡 考点:会画树→二叉树、森林→二叉树的转换图


✅ 树和森林的遍历

表格

遍历方式 森林
先根遍历 根 → 子树先根 树先根 → 森林先根
后根遍历 子树后根 → 根 森林后根 → 树后根

💡 注意:树的先根遍历 ≈ 二叉树的前序遍历

树的后根遍历 ≈ 二叉树的后序遍历


四、树与二叉树的应用

✅ 哈夫曼(Huffman)树与编码

✅ 哈夫曼树定义:
  • 一棵带权路径长度最小的二叉树
  • 所有叶子节点有权重(如字符频率)
✅ 构造方法(贪心):
  1. 将所有叶子节点放入优先队列(小顶堆)
  2. 取出两个最小权值的节点,合并为一个新节点(权值为和)
  3. 将新节点放回队列
  4. 重复直到只剩一个节点(根)

💡 考点:构造哈夫曼树、计算带权路径长度(WPL)、写出哈夫曼编码

✅ 哈夫曼编码
  • 每个字符对应从根到叶子的一条路径
  • 左边标 0,右边标 1
  • 得到唯一前缀码(无歧义)

✅ 优点:压缩率高,广泛用于文件压缩(ZIP、JPEG)


✅ 并查集(Union-Find)

✅ 定义:
  • 一种用于管理集合合并与查询的数据结构
  • 支持两种操作:
    • find(x):查找 x 所在集合的代表元(根)
    • union(x, y):合并 x 和 y 所在集合
cpp 复制代码
#define SIZE 100
int UFSets[SIZE]; // 集合元素数组(双亲指针数组)

// 并查集的初始化操作
void Initial(int S[]) { // S即为并查集
	for(int i = 0; i < SIZE; i++) { // 每个自成单元素集合
		S[i] = -1;
	}
}

// Find操作
int Find(int S[], int x) {
	int root = x;
	while(S[root] >= 0) { // 循环查找x的根
		root = S[root];
	}
	while(x != root) { // 压缩路径
		int t = S[x]; // t指向x的父结点
		S[x] = root; // x直接挂载到根结点下面
		x = t;
	}
	return root; // 返回根结点编号
}

// Union操作
void Union(int S[], int Root1, int Root2) {
	if(Root1 == Root2) return; // 要求Root1和Root2是不同的集合
	if(S[Root2] > S[Root1]) { // Root2结点数更少
		S[Root1] += S[Root2]; // 累加到集合树的结点总数
		S[Root2] = Root1; // 小树合并大树
	} else { // Root1结点数更少
		S[Root2] += S[Root1]; // 累加结点总数
		S[Root1] = Root2; // 小树合并大树
	}
}
✅ 实现方式:
  • 用数组存储父节点
  • 使用路径压缩按秩合并优化效率
✅ 时间复杂度:
  • 近似 O(α(n)),其中 α(n) 是阿克曼函数的反函数(极慢增长)

💡 应用场景:

  • 图的连通性检测
  • 最小生成树(Kruskal 算法)
  • 等价类问题(如朋友圈)

✅ 考点:理解并查集原理,能实现 findunion 函数


五、高频考点总结

题型 考点
选择题 - 二叉树性质(叶子数、度为2的节点数) - 遍历顺序 - 哈夫曼树 WPL 计算 - 并查集时间复杂度
填空题 - 写出前/中/后序遍历序列 - 哈夫曼编码表
简答题 - 说明线索化的作用 - 描述森林转二叉树的过程 - 解释并查集如何维护集合
算法题 - 构造哈夫曼树 - 实现并查集的 findunion

六、一句话口诀(背下来!)

"二叉树三种遍历,线索化方便找前后;
树转二叉靠兄弟,哈夫曼编码省空间;
并查集合并快,路径压缩效率高!"


相关推荐
WHS-_-20222 小时前
Tx and Rx IQ Imbalance Compensation for JCAS in 5G NR
javascript·算法·5g
余瑜鱼鱼鱼2 小时前
Java数据结构:从入门到精通(九)
数据结构
float_六七2 小时前
设备分配核心数据结构全解析
linux·服务器·数据结构
jinmo_C++2 小时前
Leetcode_59. 螺旋矩阵 II
算法·leetcode·矩阵
夏鹏今天学习了吗2 小时前
【LeetCode热题100(81/100)】零钱兑换
算法·leetcode·职场和发展
北京地铁1号线2 小时前
Embedding 模型的经典benchmark:MTEB
算法
焦糖玛奇朵婷2 小时前
盲盒小程序:开发视角下的功能与体验
java·大数据·jvm·算法·小程序
QiZhang | UESTC3 小时前
【豆包生成,写项目看】探寻最优学习路径:线性回归从框架补全到从零手写
学习·算法·线性回归
知乎的哥廷根数学学派3 小时前
基于多物理约束融合与故障特征频率建模的滚动轴承智能退化趋势分析(Pytorch)
人工智能·pytorch·python·深度学习·算法·机器学习