哈夫曼树

1404 字
7 分钟
哈夫曼树
Warning

含AI生成内容

哈夫曼树#

定义#

哈夫曼树(Huffman Tree),也称最优二叉树(Optimal Binary Tree),是带权路径长度(Weighted Path Length, WPL)最小的二叉树。

带权路径长度(WPL)#

WPL 定义为所有叶子结点的权值路径长度(从根到该叶子的边数)的乘积之和:

WPL = Σ wᵢ × lᵢ

其中 wᵢ 是第 i 个叶子结点的权值,lᵢ 是从根到该叶子的路径长度(边数)。

示例:对三个权值 {2, 3, 5},不同的二叉树形态对应的 WPL 不同:

形态1: 5 形态2: 2 形态3: 3
/ \ / \ / \
2 3 5 3 5 2
WPL1 = 2×2 + 3×2 + 5×1 = 15
WPL2 = 5×2 + 3×2 + 2×1 = 18
WPL3 = 5×2 + 2×2 + 3×1 = 17

形态 1 即为哈夫曼树,因为它的 WPL 最小。

哈夫曼树的性质#

性质说明
初始 n 个叶子构建出的哈夫曼树共有 2n - 1 个结点
无度为 1 的结点所有非叶子结点都有两个孩子(度为 2)
不唯一权值相同或合并顺序不同时,可能得到不同的哈夫曼树
WPL 唯一虽然树的形态可能不同,但最小 WPL 值是固定的

证明 2n-1 个结点:n 个叶子结点合并 n-1 次产生 n-1 个新结点,总数为 n + (n-1) = 2n-1。


哈夫曼树的构建算法#

算法步骤(贪心策略)#

  1. 将 n 个权值看作 n 棵只有根结点的二叉树,构成森林 F
  2. 每次从 F 中选取权值最小的两棵树作为左右子树,合并为一棵新树,新树的根权值为左右子树权值之和
  3. 从 F 中删除这两棵树,加入新树
  4. 重复步骤 2-3,直到 F 中只剩一棵树

示例:权值 {7, 5, 2, 4}

Step 1: 选出 2 和 4 → 合并为 6
F: {7, 5, 6}
Step 2: 选出 5 和 6 → 合并为 11
F: {7, 11}
Step 3: 选出 7 和 11 → 合并为 18
F: {18} → 完成
最终树形:
18
/ \
7 11
/ \
5 6
/ \
2 4
WPL = 7×1 + 5×2 + 2×3 + 4×3 = 7 + 10 + 6 + 12 = 35

WPL 的等价计算#

哈夫曼树的 WPL 等于所有非叶结点的权值之和。在上例中:

WPL = 11 + 6 + 18 = 35

这是因为每个非叶结点的权值恰好是其子树所有叶子权值之和,在合并过程中被重复累加,最终等价于 Σ 叶子权值 × 路径长度。

时间复杂度#

  • 使用最小堆(优先队列)实现时,每次取最小元素 O(log n),共 n-1 次合并
  • 总时间复杂度:O(n log n)
// 哈夫曼树结点结构
typedef struct {
int weight;
int parent, lchild, rchild;
} HTNode, *HuffmanTree;

哈夫曼编码#

基本概念#

哈夫曼编码(Huffman Coding)是一种基于哈夫曼树的变长编码方案,广泛用于数据压缩。

构建方法#

  1. 统计每个字符的出现频率作为权值
  2. 用这些权值构建哈夫曼树
  3. 从根到每个叶子的路径上,左分支标记 0,右分支标记 1(或相反)
  4. 从根到叶子的路径上的 0/1 序列即为该字符的哈夫曼编码

哈夫曼编码的重要性质#

性质说明
前缀编码任一字符的编码不是另一字符编码的前缀(唯一可译性)
最优性给定字符频率,WPL 最小意味着平均编码长度最短
变长编码高频字符用短编码,低频字符用长编码
无损压缩可以完全还原原始数据

示例:字符 {a, b, c, d} 频率 {4, 2, 1, 1}

哈夫曼树:
8
/ \
4 4 (权值和)
/ \
2 2
/ \
1 1
编码:
a: 0 (频率 4,1 位)
b: 10 (频率 2,2 位)
c: 110 (频率 1,3 位)
d: 111 (频率 1,3 位)
平均编码长度 = (4×1 + 2×2 + 1×3 + 1×3) / 8 = 1.75 位/字符

前缀编码的重要性#

若编码集为 {0, 10, 110, 111},对序列 0110111 可以唯一解码(0 | 110 | 111),不会出现歧义。这是因为哈夫曼树中每个叶子对应一个编码,路径不会相互包含。

相比之下,若采用 {0, 01, 10},则 010 可以解码为 0|1001|0,存在歧义。


哈夫曼编码的应用#

应用说明
ZIP 压缩Deflate 算法使用哈夫曼编码压缩文件
JPEG 图像对 DCT 变换后的系数进行哈夫曼编码
MP3 音频对量化后的频域系数进行哈夫曼编码
通信编码信道编码中用于最小化平均传输比特数

静态哈夫曼 vs 动态哈夫曼#

类型优点缺点
静态哈夫曼编码简单需要传送码表到解码端
动态哈夫曼无需传送码表实现复杂,实时更新编码树

考研高频考点#

  • 给定一组权值,计算哈夫曼树的 WPL(选择题和简答题都考)
  • 构建哈夫曼树的过程题(权值合并顺序)
  • 哈夫曼树的无度为 1 结点性质
  • 哈夫曼编码的前缀特性判断
  • 给定字符频率,计算平均编码长度
  • 已知某些字符的编码,判断是否为合法哈夫曼编码(是否前缀编码)
  • 辨析:哈夫曼编码不唯一(左右分支标记可互换,同权值合并顺序可调),但 WPL 唯一

关联页面#

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

哈夫曼树
https://lingluoa.icu/posts/huffman-tree/
作者
lingluoa
发布于
2026-07-06
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
lingluoa
Hello, I'm lingluoa.
公告
欢迎来到我的博客!不定期更新中。
文章目录
标签
站点统计
文章
53
分类
9
标签
75
总字数
175,771
运行时长
0
最后活动
0 天前
站点信息
构建平台
ESA Pages
博客版本
Firefly v6.15.6
文章许可
CC BY-NC-SA 4.0