初识哈夫曼编码

2023-12-05

1.什么是哈夫曼编码?

1.什么是编码?

编码就是把一些信息比如文字文件、视频文件转成0101的一堆数字存储起来,这些数字就是编码,它们需要满足数字与字符的一一对应关系。当然还必须满足可以由这一堆数字转回到文件信息,这样的编码才是有意义的。

2.问题说明

1.上图编码问题

“我是小张”这句话的确被转成了编码,但是编码“011011”就一定是“我是小张”吗?

其实不难看出,“011011”当然也可以代表“我张我张”。原因很简单,在面对数字1时,我到底是把它当作“是”,还是跟后面的数字结合起来组成其他字符呢?其实0也会有这样的烦恼,只是我们现在编码很少。举个例子,如果“子”的编码是“100",那么我的句子中如果有“子”,其实我是组成“是我我”的。也就是再面对数字0,也会遇到同样的问题。

那么肯定就有聪明的宝子们想到了,让编码等长不就好了吗。

2.等长编码问题

常用汉字是6500个,每个汉字给它一个编码,那么想要实现编码的转换就得13位二进制码,如果用等长编码,当这个汉字的编码只是“10”或“1”,前面就要补十几位的0,这么看来英语还挺好的,手动狗头一下,毕竟只有26个英文字母嘛,最多就是再加个空格符。但是其实也是需要五位二进制码去覆盖所有字母的,难免会有一些字母的编码小,需要补0,这样就浪费了内存空间。

有没有既能无歧义的转回文件,又能使内存消耗最少的方法呢?

聪明的哈夫曼就想到了!

3.解法优化——哈夫曼编码

1.哈夫曼树的形成过程

这里建议看b站up幽蓝伊梦的哈夫曼树详解,这里就不再口述,视频会讲的比较清楚。

2.哈夫曼树的特点说明

图片注明:图(1)与图(2)对比想说明在哈夫曼树时,新节点在左在右都无所谓(即B节点可以在3节点的左边也可以在3节点的右边,A节点同理)

图(3)与图(1)、(2)对比想说明树枝上哪边标1、哪边标0都不重要,这棵树甚至可以是第一层标左边1右边0,第二层标左边0右边1,第三层标左边1右边0的,(如果图1的树按上述说法标注1、0,则编码结果是与图2相同的,感兴趣的同学不妨自己动手一试)

图(4)与图(1)、(2)、(3)对比是想说明对于B、C字符,它们出现的次数是相同的,所以先放谁其实都是无所谓的,对最终的编码长度也并不会造成影响

哈夫曼树是灵活的,哈夫曼树的不同会导致编码结果的不同,但都是对的,都解决了之前提到的编码问题

最终的编码结果的二进制数个数是相同的(长度相同)

3.解决问题1

在哈夫曼编码中,我们不会再遇到见到1个“0”不知道是看作单独的0还是与后边的数结合的问题了。“1”也一样。

我们不妨再用树的形式来看一下之前遇到的问题

显然它与哈夫曼树的区别就是B这个节点处的处理,对于上图,当遇到数字“1”时,我就无法确定它是B还是到达D是路上所经过的1

而对于哈夫曼树,我在同一个位置处把它处理成了非字符节点,确保了第一个分支上的1只能作为通往字符节点的路,从哈夫曼树的结构上,我们也看到了,其实除了最后一层以外,其他的每层只有一个字符节点,也就保证了要么你到达该层的字符节点,要么你就只是作为一个站点路过。

4.问题2的优化

对于内存的优化,哈夫曼编码前需要先计算每个字符出现的次数,从出现次数最少的字符开始从下往上建树,这就保证了出现次数越多的字符,它的所处层级越高,距离根节点也就越近,路径越短,编码越短,这样短的编码赋给出现次数多的字符,长的编码赋给出现次数少的字符,自然总的编码长度就短,所占内存也就少。

2.哈夫曼编码实现文件压缩的原理

我们都知道计算机是利用ASCII码表实现将字符转成0101的二进制数的,而哈夫曼编码则是针对一份具体的文件,生成它自己的一份字符与二进制数相对应的码表,这个码表是针对这一个文件生成的,因此满足上述的内存优化,相比计算机自带的ASCII码表来说,所占内存固然更小,也就实现了文件的压缩。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

初识哈夫曼编码 的相关文章

  • 题解 | #Quasi Binary#

    题解 Quasi Binary 这道题只让再可能的数中有0或1出现 那么最少可能方案的数量只可能是每个位上的最大的数字 因为一定要在这个位上减去这个数目的一 才可以将这位变成0 接下来就是按每 题解 奇 妙拆分 这道题思路 很简单 要求最多

随机推荐