一、对图片的压缩与解压缩,涉及以下内容:
1.文件读写
2.创建Huffman树
3.生成Huffman编码
4.压缩图片文件
5 . 解压缩图片文件
二、将项目分成三个小任务,下一任务是在上一任务的基础上完成:
1.任务一:统计权值、创建Huffman树
2.任务二:生成Huffman编码、保存压缩文件
3.任务三:解压压缩文件,恢复原文件
下面开始完整的步骤:
三、统计权值、生成Huffman树
1.Huffman树的存储结构定义
2.统计Huffman树中各结点权值大小的方法及结果
初始化权值为0,通过循环从文件头开始读取文件,直到文件结尾为止,把读到的字节赋值给无符号字符c,然后把与c同值的数组下标所在的元素权值加一。(由于!Feof函数会多读一次文件,所以需要在最后减一得到文件长度。)
程序运行结果如下:
3、 描述生成Huffman树的算法并输出Huffman树各个结点的信息
对树进行初始。由于Huffman树的结点不会超过512,可以采用顺序存储结构,初始数组HuffTreeNode[512]中所有元素包括以下信息:
⦁ b(节点表示的字节):节点表示的字节值,初始可为’\0’。
⦁ count(权值):前面读文件时已统计,此处无需统计。
⦁ parent(父节点):此时哈夫曼树未建立,故设为-1。
⦁ lchild(左孩子):此时哈夫曼树未建立,故设为-1。
⦁ rchild(右孩子):此时哈夫曼树未建立,故设为-1。
⦁ bits数组(结点对应的哈夫曼编码):此时哈夫曼树并未建立,可不设置。
HuffTreeNode[512]数组其中叶子结点在下标小的,所有的叶子结点在前面(0~255),非叶子结点在后面(256~511)。
通过循环,对权值不为0的结点通过强制转型赋与其下标一致的字符值,权值为0的不计。
然后对父节点和孩子赋初始值。图片中可能会出现256种字节,但可能某些字节并未出现,因此判断HuffTreeNode数组前256个元素有权值的元素,让这些元素做为Huffman树的叶子结点,其它的颜色不参于树的生成,提高效率。
采用简单选择排序,将HuffTreeNode数组前256个元素按权值从大到小排序,从而找到有权值的元素个数,记录叶子节点的个数,得到哈夫曼树的总结点数。
每次选HuffTreeNode数组中权值最小的两个元素,其中最小值作为树的左孩子,次小值做为树的右孩子,构建哈夫曼树的后n-1个结点,先预设一个最大权值,通过循环,parent!=-1 说明该结点已在哈夫曼树中,跳出循环重新选择新节点,通过比较找到最小结点和次小结点。然后将该树的根结点作为Huffuman树的非叶子结点。为了保存它们之间的逻辑关系,保存左右孩子的父节点设置,将根节点的权值设置为左右孩子权值之和,将根节点的左右孩子设置。在parent值是0的结点中选取count值最小的两个结点进行合并,规定最小的合并为左孩子,第二小值合并为右孩子,合并生成的根结点的count值为左右孩子权值之和。重复上述过程,直到所有结点合并成一棵树。(parent=0