哈夫曼树和哈夫曼编码
哈夫曼(Huffman)编码是个实用的压缩编码方案。
哈夫曼树
引子
我们观察以下代码:
if( a < 60) {
printf("不及格\n");
}else if( a < 70){
printf("及格\n");
}else if( a < 80){
printf("良好\n");
}else if( a < 90){
printf("优秀\n");
}
我们用树来表示这个条件结构:
由于试卷结构,绝大多数的学生成绩集中在70-89之间,因此需要我们对判断流程树进行修改,达到最高的效率。
定义与原理
我们把刚刚的分数表按照范围进行标识:
A: 0~59 5% 不及格
B: 60~69 15% 及格
C:70~89 70% 良好
D:90~100 10% 优秀
把这棵二叉树简化为叶子结点带权的二叉树(树结点间的连线相关的数叫做权,Weight)。
‘
如下:
🖊定义
- 结点的路径长度:从根节点到该结点上的路径上的连接数
如左树中C的路径长度为3
- 树的路径长度:树中每个叶子结点的路径长度之和
如左树的路径长度为
1+2+3+3=9
- 结点带权路径长度:结点的路径长度与权值的乘积
如左树中C的带权路径长度为
3*70=210
- 树的带权路径长度:
即WPL(Weighted Path Length)是树中所有叶子结点的带权路径长度之和
如左树的带权路径长度为
1*5 + 2*15 + 3*70 +3*10 = 275
;而右树的WPL为1*10 + 2* 70 + 3*5 + 3* 15 = 210
。
WPL的值越小,说明构造出来的二叉树性能越优。显然右树更出彩。
我们把构造出的最优二叉树称为哈夫曼树。
🎯构造规则
例如:频率表 A:60, B:45, C:13 D:69 E:14 F:5 G:3
⭐️第一步:找出字符中最小的两个,小的在左边,大的在右边,组成二叉树。在频率表中删除此次找到的两个数,并加入此次最小两个数的频率和。
F和G最小,因此如图,从字符串频率计数中删除F与G,并返回G与F的和 8给频率表