一.哈夫曼树
- 给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
- 话不多说,直接上图:
求出三个二叉树的带权路径长度WPL,其中WPL( c )最短,c为哈夫曼树。 - 那么如何构造哈夫曼树?哈夫曼给出了哈夫曼算法:
①.根据给定的n个权值构造成的n棵二叉树集合F,其中每棵二叉树Ti中只有一个带权为wi的根结点,其左右子树均为空。
②.在F中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树,且置新的二叉树的根结点的权值为左右子树上根结点的权值之和。
③.在F中删除这两棵左右子树,并将新得到的二叉树加入F中。
④.重复步骤②和步骤③直到F只含一棵树为止,这棵树便是哈夫曼树。
下图对应其过程:
二.哈夫曼树的应用—哈夫曼编码
- 快速远距离通信的主要手段是电报,在传输的过程中,需要将传送的文字转换为二进制的字符组成的字符串,例如" A B A C C D A",它只有四种字符,若将其分别编码为00,01,10,11,则上述电文便转换为"00010010101100",总长14位,对方接收时,可按两位一份进行译码。
- 我们希望传送电文时的总长尽可能的短,如果对每个字符设计长度不等的编码,例如0,00,1,01,则上述电文便转换为"000011010",总长9位,缩短了其长度,但译码的时候会有多种译法。因此,我们若要设计长度不等的编码,则必须任一个字符的编码都不是另一个字符的编码的前缀,这种编码叫做前缀编码。
- 我们可以利用二叉树来设计二进制的前缀编码,设4个叶子结点即为A,B,C,D四个字符,且约定左分支表示字符0,右分支表示字符1,则二叉树如下图:
- 这样得到的编码必为前缀编码,但怎么使电文的总长最短?这一问题又转换到了求解哈夫曼树的问题上了,我们将电文中字符出现的次数看为权值,则根据哈夫曼算法构建出来的哈夫曼树,带权路径长度WPL最短,即电文的总长最短。
- 由此可见,设计电文总长最短的二进制前缀编码即为以n种字符出现的频率作为权值,设计一棵哈夫曼树的问题,由此得到的二进制前缀编码便称为哈夫曼编码。
- 由哈夫曼的特性可知,哈夫曼树中没有度为1的结点(这类树又称为严格的或正则的二叉树),则一棵有n个叶子结点的哈夫曼树共有2n-1个结点。
因为:∵N=n2+n1+n0;
∴N=n2+n0;
又∵n0=n2+1(二叉树的重要特性);
∴N=2n-1;