给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
有点云里雾里的感觉...
先给个例子:
比如现在有一串字母ACEFBBABFEAAAABCDEFGA...
首先统计出每种字符出现的频率!(也可以是概率)//权值
例如:频率表
| 字符 | 频率 |
|---|---|
| A | 60 |
| B | 45 |
| C | 13 |
| D | 69 |
| E | 14 |
| F | 5 |
| G | 3 |
第一步:找出字符中最小的两个,小的在左边,大的在右边,组成二叉树。在频率表中删除此次找到的两个数,并加入此次最小两个数的频率和。
F和G最小,因此如图,从字符串频率计数中删除F与G,并返回G与F的和 8给频率表

现在频率表变为
| 字符 | 频率 |
|---|---|
| A | 60 |
| B | 45 |
| C | 13 |
| D | 69 |
| E | 14 |
| FG | 8 |
最小的是 FG:8与C:13,因此如图,并返回FGC的和:21给频率表。

重复第一步:
如图



| 字符 | 编码 |
|---|---|
| A | 10 |
| B | 01 |
| C | 0011 |
| D | 11 |
| E | 000 |
| F | 00101 |
| G | 00100 |
该哈夫曼树的带权路径长度为:60*2+45*2+13*4+69*2+14*3+5*5+3*5 = 482
那么当我想传送 ABC时,编码为 10 01 0011
对比
- 不用哈夫曼编码:
理论字符串大小(假设http用ASCII码传输,一个字母占用一个字节):
传输大小 = 字符串长度*1字节 = 209*1字节 = 209字节 - 采用哈夫曼编码:
传输大小 =哈夫曼树的信息(频率表) + 带权路径长度/8 ≈7*3 + 482/8 ≈21 + 61 = 82字节
| 字符 | 频率 |
|---|---|
| A | 60 |
| B | 45 |
| C | 13 |
| D | 69 |
| E | 14 |
| F | 5 |
| G | 3 |
这里的7*3只是个假设,具体没研究过,这里假设每个字符一个字节,存储的频率用二个字节;482需要除以8是因为482bit转成字节需要除以8
可以看到,采用哈夫曼编码可以节约很多空间,虽然需要额外传输哈夫曼树的信息
事实上,前端不需要手动把数据用哈夫曼编码然后进行http传输,gzip压缩(采用LZ77算法和Huffman编码的压缩原理)已经帮我们做了这方面的工作,经过gzip压缩过的数据大大节省传输大小。所以开启gzip是多么重要。
Huffman编码在前端的应用
没有!
Huffman编码一般用在通信领域,还有就是图像压缩领域等。
前端一般不需要刻意用Huffman对数据进行编码,因为别人已经帮我们做好了,比如JPEG图片,gzip