Huffman 哈夫曼编码与译码的原理剖析及C++实现
原理
我们在信息存储时,希望以最少的空间去存储最大的数据,方便数据的传输,那么该怎样做呢?
我们想到将源信息转化为01序列存储,但是这样以来又有一个问题,就是子串匹配问题,我们为了解决这个方法,想到了前缀编码,即每一个字符对应的01编码都不能是另一个字符的01编码的子串。在这其中我们发现,前缀编码其实就是对应了二叉树的序列。此时,二叉树可以有多种。
我们对子串匹配时的效率问题还是不满意,希望经常被编码的字符它的编码短一些,这样将文件的编码就能尽可能短一些,就所以我们想到了用权值代替字符出现的频率(也是概率),构造一颗带权二叉树去编码。那么在构建这样的树的时候,我们就想到了用最优二叉树的概念去构建这么一棵树。
什么是最优二叉树?在《离散数学》(左孝凌版本) 有如下定义:
定理一:设T为带权 w1 <= w2 <= ... <= wt 的最优二叉树,则
1)带权 w1,w2 的树叶 Vw1, Vw2 是兄弟。
2)以树叶Vw1,Vw2为儿子的分枝点,其通路长度最长。
定理二:设T为带权 w1 <= w2 <= ... <= wt 的最优二叉树,若将以带权 w1 和 w2 的树叶为儿子的分枝点改为带权 w1+w2 的树叶,得到一颗新树T‘,则T’也是二叉树。
上述两条定理就是构造 HuffmanTree 的基础,选取两个权最小的结点,改为带权为它们之和的结点。由于这样构建会导致权值大的离 root 近,这样就达到了前缀编码后的文件尽可能少的目地。
译码的本质就是子串匹配,这是串的内容,很基础,这里就不多谈了,
Huffman code / Huffman transcode的理论基础就是这样了。
代码
github地址:Huffman ,C++实现,欢迎探讨