天天看点

Huffman树及Huffman编码

1 Huffman树,又称最优树,是一类带权路径长度最短的树。

2 详解

2.1 从树中一个结点到另一个结点之间的分支构成这两个结点之间的路径,路径上的分支数目称作路径长度。

2.1 树的路径长度是从树根到每一个结点的路径长度之和。

2.3 树的带权路径长度为树中所有叶子结点的带权路径长度之和,通常记做 WPL=

∑ w klk(k=1,2...n)。

2.3 假设有n个权值{w1,w2,...,wn},试构造一棵有n个叶子结点的二叉树,每个叶子结点带权为wi,则其中带权路径长度为WPL最小的二叉树称作二叉树或huffman树。

3 如何构造Huffman树?Huffman最早给出了一个带有一般规律的算法,俗称Huffman算法

3.1 根据给定的n个权值{w1,w2,..,wn}构成n棵二叉树的集合F={T1,T2,...,Tn},其中每棵二叉树Ti中只有一个带权为wi的根结点,其左右子树均空。

3.2 在F中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为其左,右子树上根结点的权值之和。

3.3 在F中删除这两棵树,同时将新得到的二叉树加入F中。

3.4 重复(2)和(3),直到F中只含一棵树为止。这棵树便是Huffman树。

4 Huffman编码

4.1 电报在远距离通讯的时候,要把文字转换成由二进制的字符组成的字符串。例如'A B A C C D A',它只有4种字符,只需要两个字符的串便可分辨。假设A B C D的编码分别是00,01,10和11,则上述7个字符的电文便为'00010010101100',总长14位,对方接收时,可二位一份进行译码。

4.2 为了在传送电文时,希望总长度尽可能地短,对每个字符设计长度不等的编码,且让电文中出现次数较多的字符采用尽可能短的编码,则传送电文的总长便可减少。如果设计 A B C D 的编码分别为0 00 1和01,则上述7个字符的电文可转换成总长为9的字符串'000011010'。但是这种电文无法翻译,前四个字符串'0000'就可能有多种译法,或是'AAAA',或是'ABA'等。因此,若要设计长短不等的编码,则必须是任一个字符的编码都不是另一个字符的编码的前缀,这种编码称作前缀编码。

4.3 可以利用二叉树来设计二进制的前缀编码。假设有一棵如下图所示的二叉树,其4个叶子结点分别表示A B C D这4个字符,且约定左分支表示字符'0',右分支表示字符'1',则可以从根结点到叶子结点的路径上分支字符组成的字符串作为该叶子结点字符的编码。可以证明,如此得到的必为二进制前缀编码。如由图所得A B C D的二进制前缀编码分别为0 10 110和111。

Huffman树及Huffman编码

4.4 如何得到使电文总长最短的二进制前缀编码呢?

假设每种字符在电文中出现的次数为wi,其编码长度为li,电文中只有n种字符,则电文总长为∑wklk (k=1,2...n)。对应到二叉树上,若置wi为叶子结点的权,li恰为二叉树上带权路径长度。由此可见,设计电文总长最短的二进制前缀编码即为以n种字符出现的频率作权,设计一棵huffman树的问题,由此得到的二进制前缀编码便称为huffman编码。

4.5 由于Huffman树中没有出度为1的结点,则一棵有n个叶子结点的Huffman树共有2n-1个结点。

具体实现:[email protected]:hglspace/HuffmanTree.git

事例图:(数字代表的是叶子结点的权值,不是路径;路径约定的是左分支是0,右分支是1)

Huffman树及Huffman编码

继续阅读