Huffman编码文件压缩

1. 实验目的与要求

在学习和理解二叉树的原理、构造及遍历方法的基础上,应用所学知识来解决实际问题。

本实验将通过一个实际应用问题的解决过程掌握Huffman树的构造、Huffman编码的生成及基于所获得的Huffman编码压缩文本文件。

涉及的知识点包括树的构造、遍历及C语言位运算和二进制文件。

2. 实验内容

Huffman编码文件压缩

【问题描述】

编写一程序采用Huffman编码对一个正文文件进行压缩。具体压缩方法如下:

1.    对正文文件中字符(换行字符'\n'除外,不统计)按出现次数(即频率)进行统计。

2.    依据字符频率生成相应的Huffman树(未出现的字符不生成)。

3.    依据Huffman树生成相应字符的Huffman编码。

4.    依据字符Huffman编码压缩文件(即将源文件字符按照其Huffman编码输出)。

说明:

1.    只对文件中出现的字符生成Huffman树,注意:一定不要处理\n,即不要为其生成Huffman编码。

2.    采用ASCII码值为0的字符作为压缩文件的结束符(即可将其出现次数设为1来参与编码)。

3.    在生成Huffman树前,初始在对字符频率权重进行(由小至大)排序时,频率相同的字符ASCII编码值小的在前;新生成的权重节点插入到有序权重序列中时,若出现相同权重,则将新生成的权重节点插入到原有相同权重节点之后(采用稳定排序)。

4.   在生成Huffman树时,权重节点在前的作为左孩子节点,权重节点在后的作为右孩子节点。

5.    遍历Huffman树生成字符Huffman码时,左边为0右边为1。

6.   源文件是文本文件,字符采用ASCII编码,每个字符占8个二进制位;而采用Huffman编码后,高频字符编码长度较短(小于8位),因此最后输出时需要使用C语言中的位运算将字符的Huffman码依次输出到每个字节中。

【输入形式】

对当前目录下文件input.txt进行压缩。

【输出形式】

将压缩后结果输出到文件output.txt中,同时将压缩结果用十六进制形式(printf("%x",...))输出到屏幕上,以便检查和查看结果。

3. 实验准备

1.文件下载

  从教学平台(judge.buaa.edu.cn)课程下载区下载文件lab_tree2.rar,该文件中包括了本实验中用到的文件huffman2student.c和input.txt:

l  huffman2student.c:该文件给出本实验程序的框架,框架中部分内容未完成(见下面相关实验步骤),通过本实验补充完成缺失的代码,使得程序运行后得到相应要求的运行结果;

l  input.txt:为本实验的测试数据。

     2. huffman2student.c文件中相关数据结构说明

  结构类型说明:

struct tnode {     //Huffman树结构节点类型

      char c;         

      int weight;

      struct tnode *left;

      struct tnode *right;

      } ;

  结构类型struct tnode用来定义Huffman树的节点,其中;

1)对于树的叶节点,成员c和weight用来存放字符及其出现次数;对于非叶节点来说,c值可不用考虑,weight的值满足Huffman树非叶节点生成条件,若p为当前Huffman树节点指针,则有:

p->weight = p->left->weight + p->right->weigth;

2)成员left和right分别为Huffman树节点左右子树节点指针。

全局变量说明:

  int Ccount[128]={0};              

       struct tnode *Root=NULL;           

char HCode[128][MAXSIZE]={0};    

      int Step=0;                                        

FILE *Src, *Obj;

整型数组Ccount存放每个字符的出现次数,如Ccount[‘a’]表示字符a的出现次数。

变量Root为所生成的Huffman树的根节点指针。

数组HCode用于存储字符的Huffman编码,如HCode['a']为字符a的Huffman编码,本实验中为字符串”1000”。

变量Step为实验步骤状态变量,其取值为1、2、3、4,分别对应实验步骤1、2、3、4。

变量Src、Obj为输入输出的文件指针,分别用于打开输入文件“input.txt”和输出文件“output.txt”。

4. 实验步骤

【步骤1】

1)        实验要求

在程序文件huffman2student.c中“//【实验步骤1】开始”和“ //【实验步骤1】结束”间编写相应代码,以实现函数statCount,统计文本文件input.txt中字符出现频率。

//【实验步骤1】开始

void statCount()

{

 

 

      }

      //【实验步骤1】结束

2)        实验说明

函数statCount用来统计输入文件(文件指针为全局变量Src)中字符的出现次数(频率),并将字符出现次数存入全局变量数组Ccount中,如Ccount[‘a’]存放字符a的出现次数。

注意:在该函数中Ccount[0]一定要置为1,即Ccount[0]=1。编码值为0(’\0’)的字符用来作为压缩文件的结束符。

3)        实验结果

函数print1()用来打印输出步骤1的结果,即输出数组Ccount中字符出现次数多于0的字符及次数,编码值为0的字符用NUL表示。完成【步骤1】编码后,本地编译并运行该程序,并在标准输入中输入1,程序运行正确时在屏幕上将输出如下结果:

鍥�.png

 图1步骤1运行结果

在本地运行正确的情况下,将你所编写的程序文件中//【实验步骤1】开始”和“ //【实验步骤1】结束”间的代码拷贝粘贴到实验报告后所附代码【实验步骤1】下的框中,然后点击提交按钮,若得到如下运行结果(测试数据1评判结果为完全正确):

鍥�b.png

表明实验步骤1:通过,否则:不通过。

  • 29
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值