目录
哈夫曼压缩与解压缩(c语言版)
一:引言
学过数据结构的同学,应该都听过哈夫曼树,和哈夫曼压缩算法,今天小编向大家讲解哈夫曼压缩与压缩的过程以及代码也算是记录一下自己所学所做的东西。
哈夫曼压缩,其实效率不是很高,一般情况下压缩率13%左右,特殊情况下效率很高(频率高的字符的情况)。但是尝试自己去完成它,对你的代码能力有很大的提升。下面开始讲解
二:主要原理
1.哈夫曼树 :
给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近(频率越高的结点离根越进)。
以 下数组为例,构建哈夫曼树
int a[] = {0,1,2,3,4,5,6,7,8}
我们可以发现以下规律
1:9个数构成的哈夫曼树一共有17个结点,也就是可以n个数可以生产2*n-1个结点
2:数字越大的数离根节点越近,越小的数离根节点越近。
2.如何利用haffman编码实现文件压缩:
比如abc.txt文件中有以下字符:aaaabbbccde,
1.进行字符统计
aaaabbbccde
a : 4次
b : 3次
c : 2次
d : 1次
e : 1次
2.用统计结果构建哈夫曼树
3.用哈夫曼树生成哈夫曼编码(从根结点开始,路径左边记为0,右边记为1):
a的编码:1
b的编码:01
c的编码:000
d的编码:0011
e的编码:0010
4.哈夫曼编码代替字符,进行压缩。
源文件内容为:aaaabbbccde
将源文件用对应的哈夫曼编码(haffman code)替换,则有:11110101 01000000 00110010 (总共3个字节)
由此可见,源文件一共有11个字符,占11字节的内存,但是经过用haffman code替换之后,只占3个字节,这样就能达到压缩的目的
三:主要技术点
1.哈夫曼树算法(哈夫曼压缩的基本算法,如何不懂该算法,小编建议先学习下该算法)
2.哈希算法(字符统计时候会用到)
3.位运算(涉及到将指定位,置0或置1)
4.内存对齐模式(小编在这里踩过坑,非常重要)
5.存储模式(大端存储,小端存储,能看懂文件16进制的形式)
6.主函数带参(很简单)
7.设置压缩密码,解压输入密码解压(小编自己加的内容)
四:实现过程
1.压缩:
1.遍历文件每个字节,统计所有的字符和其频率,
2.构建哈夫曼树
3.遍历树,给叶子节点生成哈夫曼编码
4.将字符和其频率,以及密码,写入新文件。
5.再次遍历文件每个字节,将该字节内容用哈夫曼编码代表,将哈夫曼编码写入文件。
2.解压缩:
1.从文件中将将字符和其频率读出来,生成一张表。读之前可以先验证输入密码是否正确
2.用改表构建哈夫曼树。
3.遍历哈夫曼树,给叶子节点生成哈夫曼编码
4遍历文件每个bit位,按照哈夫曼编码,得到数个bit所对应得到字符,将该字符写入文件。
五:详细分析,及代码实现
三个必要的位运算,(这三个方法是他人提供)
//判断指定位是否为0,若index位为0,则GET_BYTE值为假,否则为真
#define GET_BYTE(value, index) (((value) & (1 << ((index) ^ 7))) != 0)
//将指定位,置为1
#define SET_BYTE(value, index) ((value) |= (1 << ((index) ^ 7)))
//将指定位,置为0
#define CLR_BYTE(value, index) ((value) &= (~(1 << ((index) ^ 7

1238

被折叠的 条评论
为什么被折叠?



