FGK adaptive Huffman encode to compress file

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

FGK算法的原理

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

编码
在这里插入图片描述
解码
在这里插入图片描述
①编码器和解码器要用完全相同的Initial_code()和update_tree()。 ②Initial_code为字符分配初始化编码,我采用的就是ASCII码。
③update_tree是构造自适应赫夫曼编码的过程,把读取到的字符次数加一并且更新树。

核心代码

结构体

节点结构体
在这里插入图片描述
字符结构体
在这里插入图片描述

encode
create_tree():初始化赫夫曼树

在这里插入图片描述
每次读取一个字符,判断该字符是否出现过,如果已经出现过则输出该字符在树中的编码,在更新节点的次数以及更新树。如果是一个新字符,则先输出树中当前NEW的编码,NEW再分为一个NEW节点和新字符节点,最后更新树。
在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

decode

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

源代码

我的下载

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
自适应哈夫曼编码Adaptive Huffman)是一种动态建立哈夫曼编码的方法。传统的哈夫曼编码需要事先知道所有的字符及其频率,然后根据频率建立编码树。而自适应哈夫曼编码则在实际编码过程中,通过动态更新编码树来适应输入字符的变化。 自适应哈夫曼编码的主要特点是在编码过程中,不需要显式地提供字符频率的信息,而是通过根据实际输入的字符进行动态调整。在编码开始时,初始化一个初始编码树,该树包含一个特殊的权重更新节点。当输入一个字符时,首先检查该字符是否已经在编码树中存在,如果存在则直接输出该字符对应的编码,如果不存在则输出该字符的编码,并更新编码树。 更新编码树的过程分为两步。首先,根据当前输入的字符,遍历编码树找到对应的叶子节点。然后从该叶子节点开始向树根方向,逐级更新父节点的权重和位置,直到根节点。在更新过程中,为了保证编码树的平衡性,还需要处理可能出现的过度增长现象,即当某个权重达到一定阈值时,需要进行权重更新节点的旋转操作。 通过不断动态更新编码树,自适应哈夫曼编码能够提供更好的压缩效果。因为它能够更好地适应输入字符的分布,对出现频率较高的字符使用较短的编码,对出现频率较低的字符使用较长的编码。这样在编码过程中,相对常用的字符可以使用较少的比特表示,从而实现更高的压缩率。 总结来说,自适应哈夫曼编码是一种动态建立编码树的方法,能够根据实际输入的字符进行调整,并以较短的编码表示高频率的字符,以较长的编码表示低频率的字符,从而实现更好的压缩效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值