哈夫曼树与哈夫曼编码

Huffman Tree,中文名是哈夫曼树或霍夫曼树,它是最优二叉树。

引入

如果有一篇文章,由若干个字符构成。每个ABC…Z都由7位编码,文章有1w个字符,那么有7w位进行编码。一个字节8位,首位是0。需要占用1W个字节。

实际中每个单词的出现频率是不同的,比如e在文章中出现频率较高,我用5位给它编码,出现频率较低的使用7位、8位或者9位。这样效率会得到提高。

看一个具体的例子:

将百分制的成绩转化为五分制的成绩:
score<60-->grade = 1;
score<70-->grade = 2;
score<80-->grade = 3;
score<90-->grade = 4;
score>90-->grade = 5;

判定树:
哈夫曼树与哈夫曼编码_第1张图片

倘若绝大数人的成绩到90分以上,很少人不及格。而每次查询90分以上需要进行4次判断,这样效率较低

如果学生的成绩分布概率:
哈夫曼树与哈夫曼编码_第2张图片
查找效率为:0.051 + 0.151 + 0.42 + 0.33 + 0.1*4 = 3.15

修改判定树:
哈夫曼树与哈夫曼编码_第3张图片

查找效率:0.053 + 0.153 + 0.42 + 0.32 + 0.1*2 = 2.2

如何根据节点不同的查找频率构造更有效的搜索树?这就是哈夫曼树要解决的问题

哈夫曼树

先了解几个定义:
1.树的路径长度
树的路径长度是从树根到树中每一结点的路径长度之和。在结点数目相同的二叉树中,完全二叉树的路径长度最短。

2.树的带权路径长度(Weighted Path Length of Tree,简记为WPL)
结点的权:在一些应用中,赋予树中结点的一个有某种意义的实数。
结点的带权路径长度:结点到树根之间的路径长度与该结点上权的乘积。

树的带权路径长度 (Weighted Path Length of Tree):定义为树中所有叶结点的带权路径长度之和,通常记为: WPL=(W1L1+W2L2+W3L3+…+WnLn)

其中:Wi 和 Li 分别表示叶结点的权值和根到结点之间的路径长度。
树的带权路径长度亦称为树的代价。

哈夫曼树定义

假设有 n 个权值[W1,W2,…WN],构造有 n 个叶子的二叉树,每个叶子的权值是 n 个权值之一,这样的二叉树可以构造很多个,其中必有一个是带权路径长度最小的,这棵二叉树就称为最优二叉树或哈夫曼树。
哈夫曼树与哈夫曼编码_第4张图片

哈夫曼树的构造

每次把权值最小的两棵二叉树合并
例子:

2,5,1,4,3 构建哈夫曼树
首先进行排序:1,2,3,4,5 (Java中可以使用PriorityQueue构建最小堆)
每次弹出队首前两位相加,得到的和加入到最小堆中:1+2=3,
将3加入到最小堆中 变成3,3,4,5

3+3=6.最小堆:4,5,6
4+5=9.最小堆:6,9
6+9=15

哈夫曼树与哈夫曼编码_第5张图片

哈夫曼树的特点

  1. 没有度为1的结点
    • 每次构造的时候两个节点合并,所以不可能有度为1的结点
  2. n个叶子结点的哈夫曼树共有2n-1个结点
    • n0:叶节点总数 n1:只有一个儿子节点数 n2:有2个儿子的结点总数 n2=n0-1
  3. 哈夫曼树任意非叶借点的左右树交换后仍是哈夫曼树
  4. 同一组权值,可能存在不同结构的两颗哈夫曼树,但是WPL相等
    哈夫曼树与哈夫曼编码_第6张图片

哈夫曼编码

给定一段字符串,如何对字符进行编码,可以使得该字符串的编码存储空间最少?

哈夫曼树与哈夫曼编码_第7张图片
第一种方式效率低,第二种方式是一种方式的改进。只要3位,2的三次方为8,可以包含7个字符。那我们试试哈夫曼编码?

先看这一组编码:
a:1
e:0
s:10
t:11
...

当给1011的时候1011是什么字符串的编码?
aeaa:1011
aet: 1011
st:  1011

问题出现:二义性,一个编码可能有多种解码方式。
所以要解决二义性问题,采用前缀码:任何字符的编码都不是另一字符编码的前缀。在用哈夫曼编码解决这个问题之前,先看一下普通二叉树编码和哈夫曼编码的区别

二叉树用于编码

用二叉树进行编码:

  • 左右分支0、1
  • 字符只出现在叶节点上
    哈夫曼树与哈夫曼编码_第8张图片
    可以看到这样的编码代价就是 编码长度*频率

要使代价小,要使得编码效率的提升,这就转换成哈夫曼树的问题。

这个例子采用改用哈夫曼编码:
哈夫曼树与哈夫曼编码_第9张图片

哈夫曼编码的优点:

  1. 避免了二义性,每个字符都在叶节点
  2. 编码代价最小

最后解决一下前面遗留的问题:
哈夫曼树与哈夫曼编码_第10张图片
本文内容参考自:浙江大学陈越、何钦铭的公开课

你可能感兴趣的:(#,常见算法,哈夫曼树,哈夫曼编码)