FGK adaptive Huffman encode to compress file

关于自适应哈夫曼编码,常用的有FGK和Vitter。这里讲的是FGK,先放上一个关于FGK的网页,以便于理解过程。
Visual FGK

FGK算法的原理

夫曼树每一个结点有且仅有两个分支,必须总是保持其兄弟性质,也就是所有的结点都是按照从左到右、从下到上计数递增的顺序排列的。如果违反了兄弟性质,则将触发一个交换过程对节点进行重新排列。当前计数为N的节点要寻找最远的既有计数N的且顺序更前的节点进行交换(包括节点的子树),然后自身次数再更新加一。要对整棵树进行遍历,直到不能更新为止。具体例子请看上方链接。

编码
FGK adaptive Huffman encode to compress file_第1张图片
解码
FGK adaptive Huffman encode to compress file_第2张图片
①编码器和解码器要用完全相同的Initial_code()和update_tree()。 ②Initial_code为字符分配初始化编码,我采用的就是ASCII码。
③update_tree是构造自适应赫夫曼编码的过程,把读取到的字符次数加一并且更新树。

核心代码

结构体

节点结构体
FGK adaptive Huffman encode to compress file_第3张图片
字符结构体
在这里插入图片描述

encode

create_tree():初始化赫夫曼树

FGK adaptive Huffman encode to compress file_第4张图片
每次读取一个字符,判断该字符是否出现过,如果已经出现过则输出该字符在树中的编码,在更新节点的次数以及更新树。如果是一个新字符,则先输出树中当前NEW的编码,NEW再分为一个NEW节点和新字符节点,最后更新树。
FGK adaptive Huffman encode to compress file_第5张图片

getNode():判断字符是否出现过,在symbols数组中查看是否出现过该字符,如果有则返回该字符节点指针。

FGK adaptive Huffman encode to compress file_第6张图片

codeOfNode():返回该字符节点在树中的编码,左分支为0,右分支为1,以此类推。由于我是从当前节点往根节点方向得到编码,所以最后要倒转编码。

FGK adaptive Huffman encode to compress file_第7张图片

addCodeToBuffer():把字符编码写入输出文件。

FGK adaptive Huffman encode to compress file_第8张图片

update_tree():更新赫夫曼树,从当前节点逆着到根节点,更新每个节点的位置和次数和。

FGK adaptive Huffman encode to compress file_第9张图片

decode

解压文件其实就是压缩文件的逆过程,对读入的每一个bit判断是0还是1,重新构建赫夫曼树,再根据编码把bit转换成ASCII码,得到真正的字符。每一次得到一个字符后都要更新赫夫曼树,注意处理最后一个字节一共有多少位。

源代码

见我的下载

你可能感兴趣的:(浅谈)