哈夫曼编码的核心功能特简单,就两步

今天来聊聊哈夫曼编码这个事儿。其实这玩意儿吧,它的核心功能特简单,就两步:第一步是拿字频统计搞出一棵树;第二步就是拿这棵树把原文翻译成变长的比特流,这么一套组合拳下来,压缩加加密的效果就出来了。特别是在那种双向通信的信道里,两边都得备着完整的编解码器,这样数据传过去才能既省地儿,又能在那边原样复原出来。 我给你画个图,你看就明白了。这个编码器流程就跟流水线似的,从“读样本→建树→编码→吐比特流”,中间哪个环节都能换成别的法子或者自己扩展一下。 程序主体结构也很清晰,是四个模块连起来的:读样本可以是自己随便输文本,也能直接上现成的频率表;建树呢,它会根据样本动态生成一棵树,顺便还能把字符跟编码的对应关系给存下来;编码这一步就简单了,顺着原文查表套公式,最后把那些零散的比特串攒成一个大文件;写文件就直接存成.bin或者.hex的格式就行了。 这整个过程你也可以把它看成三步:先搞个密码本,再把原文变密码,最后再给密码解回来。 这里面几个关键函数也得讲讲。先是huffman_build,这是依据字符出现的频率去造那棵哈夫曼树,把节点的信息和编码的映射表都打包好返回来。encode_text是负责递归遍历文章的那个环节,照着映射表就能生成一串一串的比特流。decode_bits是解码用的,得把比特流再按那个映射表反着倒腾回原来的字符数组。save_codec是为了把树的结构和映射表存到硬盘上方便以后用。load_codec是用来读取那个存好的映射表的,好让解码器直接干活还原原文。 你看上面那个演示效果,左边的原文跟右边的二进制文件对比一下就知道压缩有多狠了;左下角那个体积对比也很直观;右下角的文章是解码还原出来的。这玩意儿的好处特别多:想自己输文本也行,想直接用现成的密码本也成;对我那篇800字的样例做了哈夫曼编码后,体积直接砍了一半多;最关键的是不管你怎么折腾那个编码过程,只要保留住那个映射表,原文就能100%还原出来,内容绝对不会丢也不会乱。