哈夫曼编码
哈夫曼树
哈夫曼树是一种带权路径长度最低的二叉树。什么是带权路径长度?树的带权路径长度是每个叶子节点出现的比重*该叶子节点到根的长度 例如,有4个叶子节点a,b,c,d。分别带权为9,4,5,2由他们构成几颗不同的二叉树,如下
这棵树的带权路径长度为wpl = 2x9+2x4+2x5+2x2=40
这棵树的带权路径长度为wpl = 1x4+2x2+5x3+3x9=50 那怎么找出这个带权路径长度最小的组合办法?可以通过构造新树的办法。将abcd4个节点看成4棵只带有根节点的树,先找出权值最小的两棵树为2和4,这两棵树可以组成新的一颗权值为6的树,现在再比较所有的树分别是权值为6、5 、9的三棵树。
再找出权值较小的两棵树,找到6和5这两棵树进行合并,合并成为
这颗权值为11的树、最后合并a得到了哈夫曼树
这棵树的wpl值为2x3+3x4+2x5+9=37,这颗树为哈夫曼树
哈夫曼树的应用(哈夫曼编码)
在数据传输中,编码中,有两种编码方式分别是等长编码、和不等长编码。如果要容易的转回字符串,可以选等长编码。但是等长编码会出现一个问题:假设字符串中有1024种字符,则我们需要设定10位二进制来表示这个字符串中的每一个字符,再假设其中一个字符出现的概率是99%,其他的字符总共加起来的概率是1%,这种情况下,会造成大量的空间浪费,因为我们本来可以用更小长度的二进制来表示这个出现概率特别大的字符。
在二进制传输的时候,用不等长编码来节省传输的二进制量,但是我们怎么使用某一种规则,将转化完的二进制回转为字符串,因为我们不知道是找1个还是2个或者是3个二进制位来表示一个字符串。这样我们需要制定一个规则为任意字符的二进制码不为别的字符的二进制码的前缀(当我们的规则用00表示一个字符时不是用001或者000去表示另外一个字符)
这样我们可以完美的用哈夫曼编码解决这个问题。比如一个文本中有abcd四个字符、a出现的概率是0.4、b出现的概率是0.3、c出现的概率是0.2、d出现的概率是0.1
我们将2叉树的左边记为0右边记为1,可以得到a的表示0 c的100,d表示101,b表示11,这样没有转回字符串的歧义,也保证了整篇文章二进制码是最短的。
任意字符不是别的编码的前缀。为什么哈夫曼树构成的编码不存在前缀码?哈夫曼树的值都在树的叶子节点中因此不会存在前缀码问题。为什么哈夫曼编码保证字符编码总长最短?因为哈夫曼树带权路径长度最短,故字符编码的总长是最短的
\