GESP 六级 第 04 讲:哈夫曼树、哈夫曼编码与格雷码

本讲定位:官方大纲把「基于树的编码」单列为知识块 2,真题给的分量也很稳定——单选第 9、10、11 题连续三道(哈夫曼 WPL、哈夫曼树结点数、格雷码性质),判断题再出 1~2 条,合计 6~10 分。

这一讲的特点是:全部靠手算,没有编程题。会画一棵哈夫曼树、会套两个公式、会背两条格雷码性质,分就拿到了。是六级仅次于六级第 01 讲的性价比之选。

对应官方大纲:六级知识块 1「树」——哈夫曼树;知识块 2「基于树的编码」——格雷编码、哈夫曼编码。

前置知识:六级第 02 讲(二叉树、遍历)、五级第 08 讲(贪心)。

代码说明:本讲代码均已用 g++ 11.5(-std=c++11)编译运行验证;WPL 程序与手算结果逐例核对,哈夫曼编码总长与真题给定答案一致。


1. 哈夫曼树是怎么来的

问题:要给一批字符编二进制码,出现次数多的字符用短码,次数少的用长码,让编码后的总长度最短。

这是一个贪心问题(五级第 08 讲讲过贪心的思路)。哈夫曼给出的贪心策略只有一句话:

$$ \boxed{\textbf{每次取出当前最小的两个数,合并成一个新数(它们的和),放回去;重复到只剩一个}} $$

1.1 手工构造(必须让学生画)

例:权值 $\{1, 2, 3, 4, 5, 6, 7, 8\}$。

轮次 取出的两个最小值 合并成 剩下的集合
1 1, 2 3 {3, 3, 4, 5, 6, 7, 8}
2 3, 3 6 {4, 5, 6, 6, 7, 8}
3 4, 5 9 {6, 6, 7, 8, 9}
4 6, 6 12 {7, 8, 9, 12}
5 7, 8 15 {9, 12, 15}
6 9, 12 21 {15, 21}
7 15, 21 36 {36} ← 只剩一个,结束

⚠️ 第 2 轮的坑:合并出来的 3 要放回集合里参与后续比较,而且它和原来的 3 地位完全一样。很多学生会一直只盯着原始数据挑,这是最常见的错误。

1.2 WPL:带权路径长度 ★

$$ \text{WPL} = \sum_{\text{每个叶子}} (\text{权值} \times \text{该叶子的深度}) $$

深度按「根到叶子的边数」算(根的深度为 0)。

但考场上没人这么算。 用下面这个捷径:

$$ \boxed{\textbf{WPL} = \textbf{所有合并操作产生的新值之和}} $$

上例:$3+6+9+12+15+21+36 = 102$。

📌 为什么这个捷径成立? 每合并一次,参与合并的那部分权值就往下沉一层,深度各加 1,对 WPL 的贡献就恰好增加「它们的和」。所以把每次合并的和累加起来,就是 WPL。

这个捷径要让学生彻底吃透:手算 WPL 完全不用画树,列个表累加即可,三十秒出答案。

1.3 真题实战

2026 年 3 月六级单选第 9 题:6 个字符,出现次数分别为 $\{2, 3, 3, 4, 6, 8\}$,求最小 WPL。