-
问题
-
现在我们要对a,b,c,d,e,f,g 7个字符进行编码,一种笨办法就是每个字符都用3bit进行编码,这样7个字符可以表示为000, 001, 010, 011, 100, 101, 110
-
按照上面的编码方式,如果a出现1次,b出现2次,c出现3次……那么这个文件一共要占(1+2+…+7) * 3 = 84bit
-
这样编码固然解决了无歧义性的问题,但是如果我们把g编码为11的话,即采用不等长编码的方式,那么其实也没有歧义的问题
-
歧义不歧义的根源在于,如果每个字符和其他字符的前缀编码不同,那么它们肯定就不会歧义,也就是说只要不出现a用11表示,b用110表示这种问题,就不会出现歧义
-
画个图表示就是下面这样
(0) 0 1 0 1 0 1 0 1 0 1 0 1 0 1
现在最下面一层是叶结点,a是最左下角的,b是a右边的……,g放在0110处也可以,放在011处也可以,因为放在哪都不会挡到其他字符的路径
另外这也说明了根节点的那个0是一个伪结点,它是永远不会用来编码字符的,因为只要放上去就会挡到其他字符
-
所以现在的需求就是:如果能让出现次数多的字符尽可能出现在靠近根结点的位置,那么编码这样的字符占用的位数就少,文件的总空间就小;另外就是注意不要让不同的字符有共同前缀,一定不要让一个字符挡到其他字符的编码路径
-
于是, Huffman提出了一种算法,还是用刚才的例子,首先让出现次数多的字符放在离根结点近的位置,也就是说出现次数少的字符放在离根结点远的位置;在没有用算法之前,所有字符各自是一个结点(一棵光杆二叉树),构成一个森林
-
现在取出权值最小的两个结点,设置一个空结点,然后让这两个结点构成空结点的左右子树(设置空结点的原因还是为了不要挡到路径上的字符);然后它们生成了一个新树,它们的联盟权值是1+2=3
null 1 2
-
然后让3,3,4,5,6,7这6颗树同台竞技,还是按照8的套路,现在这颗联盟树的权值变成6了,现在是4,5,6,6,7同台竞技
null null 3 1 2
-
null null 6 7 4 5 null 3 1 2
6,6,7,9同台竞技
null null 7 null 6 4 5 null 3 1 2
7,9,12同台竞技
null null null 6 null 7 null 3 4 5 1 2
12,16同台竞技
null null null null 6 null 7 null 3 4 5 1 2
-
现在搞定了,a:0000, b:0001, c:001, d:100, e:101, f:01, g:11
总共占用41+42+33+34+35+26+2*7 = 74bit(这个数也叫__带权路径长度__) -
总结下来就是,靠__不定长编码__节省了空间,并且靠__不同前缀__保证了非歧义性,同时Huffman又证明了这样生成的确实是最优二叉树
-
2_哈夫曼树和哈夫曼算法
猜你喜欢
转载自blog.csdn.net/captxb/article/details/88073654
今日推荐
周排行