用哈夫曼编码实现文件压缩_第1页
用哈夫曼编码实现文件压缩_第2页
用哈夫曼编码实现文件压缩_第3页
用哈夫曼编码实现文件压缩_第4页
用哈夫曼编码实现文件压缩_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、.用哈夫曼编码实现文件压缩实 验 报 告课程名称 数据结构 实验学期 2011 至 2012 学年 第 2 学期学生所在系部 计算机学院 年级 2010级 专业班级 * 学生姓名 * 学号 * 任课教师 # 实验成绩 一、实验题目哈夫曼编码实现文件压缩二、实验目的:1、了解文件的概念。2、掌握线性链表的插入、删除等算法。3、掌握Huffman树的概念及构造方法。4、掌握二叉树的存储结构及遍历算法。5、利用Huffman树及Huffman编码,掌握实现文件压缩的一般原理。三、实验设备与环境:微型计算机、Windows 系列操作系统、Visual C+6.0软件。四、实验内容:根据ASCII码文件

2、中各ASCII字符出现的频率情况创建Haffman树,再将各字符对应的哈夫曼编码写入文件中,实现文件压缩。五、概要设计:本次实验采用将字符用长度尽可能短的二进制数位表示的方法,即对于文件中出现的字符,无须全部都用8位的ASCII码进行存储,根据他们在文件中出现的频率不同,我们利用Haffman算法使每个字符能以最短的二进制字符进行存储,以达到节省存储空间,压缩文件的目的。解决了压缩需采用的算法,程序的思路已然清晰:1统计需压缩文件中每个字符出现的频率。2将每个字符的出现频率作为叶子结点构建Haffman树,然后将树中结点引向其左孩子的分支标“0”,引向其右孩子的分支标“1”;每个字符的编码即为

3、从根到每个叶子的路径上得到的0、1序列,这样便完成了Haffman编码,将每个字符用最短的二进制字符表示。3打开需压缩文件,再将需压缩文件中的每个ASCII码对应的Haffman编码按bit单位输出。4文件压缩结束。六、详细设计:(1)构造Hufffman树的方法Hafffman算法构造Huffman树步骤:I. 根据给定的n个权值w1,w2,wn,构造n棵只有根结点的二叉树,令起权值为wj。II. 在森林中选取两棵根结点权值最小的树作左右子树,构造一棵新的二叉树,置新二叉树根结点权值为其左右子树根结点权值之和。III. 在森林中删除这两棵树,同时将新得到的二叉树加入森林中。.重复上述两步,直

4、到只含一棵树为止,这棵树即哈夫曼树。对于Haffman的创建算法,有以下几点说明:a) 这里的Haffman树采用的是基于数组的带左右儿子结点及父结点下标作为存储结点的二叉树形式,这种空间上的消耗带来了算法实现上的便捷。b) 由于对于最后生成的Haffman树,其所有叶子结点均为从一个内部树扩充出去的,所以,当外部叶子结点数为m个时,内部结点数为m-1,整个Haffman树的需要的结点数为2m-1c) 初始化Hafffman树分两步进行,先将所有结点赋值,再将前m个叶子结点赋初值。d) 在查找权值最小并且父结点为空的两个结点时,通过逐个比较,将两结点的位置下标与权值分别保存。方便在与其父结点建

5、立联系时调用。开始定义Hafffman树初始化Hafffman树i=0im-1Hafffman创建完毕i+将下标为m+i的结点作为所找出的两结点的父结点,建立联系在前m+i个结点中找出权值最小并且父结点为空的两结点2)压缩过程的实现:压缩过程的流程是清晰而简单的:1创建Haffman树2打开需压缩文件3将需压缩文件中的每个ASCII码对应的Haffman编码按bit单位输出4文件压缩结束。其中,步骤1和步骤3是压缩过程的关键。a) 步骤1:这里所要做工作是得到Haffman数中各叶子结点字符出现的频率并进行创建。b) 步骤3: 将需压缩文件中的每个ASCII码对应的Haffman编码按bit单

6、位输出,这是本压缩程序中最关键的部分。这里涉及“转换”和“输出”两个关键步骤:“转换”部分大可不必去通过遍历Haffman树来找到每个字符对应的哈夫曼编码,可以将每个码值及其对应的ASCII码存放于如下所示的结构体中:typedef structchar asciiCode;unsigned long haffCode;int haffCodeLen;HaffCode;创建由该结构体结点所组成的,长度为128的一维数组codeList128,且codeList中的下标和asciiCode满足下面的顺序存放关系:codeListi.asciiCode=i;这样的话,查找某个字符inChar的Ha

7、ffman编码的工作便变得相当轻松了,如下:sHaffCode=codeListinChar.haffCode;数组codeList128的创建可以采用某种遍历方式下的按找到的字符进行置数的方式,十分的方便。以下流程图采用的是前序遍历的方式创建:说明:1 在流程图中,youBiao中存放字符对应的Haffman编码,sDepth中存放其Haffman编码的长度。2 在代码的编写过程中,可用递归调用实现。判断当前结点是否有孩子结点当前结点是否有 左孩子结点点当前结点是否有右孩子结点当前结点是否有父结点当前结点的左右孩子是否都已访问YouBiao1,sDepth+向其左结点youBiao,sDep

8、th与结点返回其父结点youBiao为Haffman编码值即开始文件的压缩编码成功 NY YyouBiao1丨0x01,sDepth+;结点指向其右结点 N Y N Y N N Y(3)“输出”部分是最重要的部分,也是最易出错的部分。每个字符要能合理的结束。这主要是为解压缩考虑的,比如在最后,这里涉及到C语言的位操作,要求这个算法能处理好以下几个问题:1)每个字符所对应的haffCode的比特位长度由523位不等长,不可少输,多输,输错任何一位,后一个字符的haffCode要紧跟在前一个字符的haffCode后面。 2)最后一个要输出的haffCode的最后一位,它恰好是位于最后一个有效字符的

9、第一位,剩下的七个空位是要用无效的haffCode加以填充的。否则,如果填充的haffCode亦为某个ascii字符的haffCode时,那么在解压缩时,则该在原被压缩文件中不存在的字符便会无中生有的在解压后的文件中出现,这显然是不正确的,应在程序中加以处理。当文件不为空时count = 0count8当前的一个字符对应 的haffCode已输出完毕将curCode中的当前位赋值给输 出字符左起的第count个位置输出字符到压缩文件读入被压缩文件的下一个字符,得到其 haffCode,设为 curCode,如是最后一个字符,则做相应y的处理Count+NYN YY N(4)main 函数部分

10、开始是否成功输入要打开文件名称是否找到 key.txt文件将 key 文件中的值作为叶 子结点构建 haffman树实现 haffman 编码输 出 ASCII 码 对 应 的 haffman 编码及其长度输出字符到压缩文件文件压缩结束,关闭打开的 文件返回 N Y N Y七、测试结果及分析:运行结果:压缩情况:实验分析: 利用Huffman树进行编码进行文件的压缩,这一思想在上一学期的离散数学课程里我们有接触到,好在当时学的还不错,所以在构建Huffman树和编码这一过程还是很容易接受的。困难就在于怎么构造出函数,构造出一个工程,做出一个能够顺利实现压缩的程序。这是动手能力,实践能力,需要长

11、时间的编程训练作为基础。数据结构是计算机程序设计的重要理论技术基础,是计算机学科的核心课程之一。它将各个抽象的数据之间的关系建立起来,无论是线性的、循环的还是分支的,都是为了建立一种方便程序的实现和运行的结构,使得数据之间不再是孤立的。它能使得我们在编程时在脑海中显现更为清晰的数据关系画面。而且在学习数据结构时我们更应该联系所属语言(我们所学的是C语言版)的特性,这样才能更好的理解数据结构的思想体系。总的来说,这次实验带来的收获是很大的,提取文件数据、分析数据、构建Huffman树、替换数据对文件进行压缩、输出文件,一次大的实验几乎运用到了我们一学期所学的所有知识。经过分、析调试和了解程序的代

12、码,巩固了上课学习的知识。平时的小程序的编写是训练,而最后的综合实验是作为验收“产品”是否合格的重要依据之一。所以,我们平时的作业要认真独立完成,否则,在考试和做综合实验时都会很吃力的。八、教师评语:教 师 评 价评定项目ABCD评定项目ABCD算法正确界面美观,布局合理程序结构合理操作熟练语法、语义正确解析完整实验结果正确文字流畅报告规范题解正确其他:评价教师签名:年 月 日附程序:Code.c#include ECBTree.h#include MyAssert.h#include #include #include #define LENGTH 128#define DEBUG 1#de

13、fine REARPOS 80char dotTxt=.txt;char dotRer=.rer;int getBinLen(unsigned long inData);void main(int argc,char* argv)long wListLENGTH;unsigned long haffCodeListLENGTH;int haffCodeLenLENGTH;HaffCode haffListLENGTH;PHtTree myHtTree;char inputFileNameLENGTH,outputFileNameLENGTH;FILE* inputFile,* outputFi

14、le,* keyFile;int fileNameLen;char inData,outputData;unsigned long curCode,tmpBinData;int curLen,realLen,curIndex;int i;int count;unsigned long rearCode;/*rear data consult*/int rearCodeLen;if (argc-keyFile not founded-n);return;for(i=0;iLENGTH-1;i+)fscanf(keyFile,%d,&wListi);fscanf(keyFile,%d;,&wLis

15、ti);myHtTree=haffmanAlgorithm(LENGTH,wList);for(i=0;irootIndex,0x000000,0,haffList);fprintf(stdout,haffCode List:rn);for(i=0;iLENGTH-1;i+)fprintf(stdout,%d,haffListi.haffCode);fprintf(stdout,%drn,haffListi.haffCode);fprintf(stdout,haffCode List Len:rn);for(i=0;iLENGTH-1;i+)fprintf(stdout,%d,haffList

16、i.haffCodeLen);fprintf(stdout,%drn,haffListi.haffCodeLen);if(DEBUG)printf(ntest start.n);curIndex=curLen=0;rearCode=haffListREARPOS.haffCode;rearCodeLen=haffListREARPOS.haffCodeLen;while(!feof(inputFile)count=0;outputData=0x01;while(count8)if(curIndex=curLen)/1.get data.if(feof(inputFile)break;inDat

17、a=fgetc(inputFile);if(inData=-1&feof(inputFile)if(count=0)outputData=-1;else/*the rear output adjust*/for(i=0;i8-count;i+)outputData(rearCodeLen-1-i)&0x01);/* the consult below will make error happen!outputData0)outputData(curLen-curIndex-1)&0x01;outputData=1;outputData|=(char)tmpBinData;/*-*/curInd

18、ex+;count+;fputc(outputData,outputFile);if(DEBUG)printf(ntest ends.n);fclose(inputFile);fclose(outputFile);getchar();return;int getBinLen(unsigned long inData)int i=0;if( inData=0)return 1;elsewhile(inData!=0)inData/=2;i+;return i;ECBTree.c#include ECBTree.h#include MyAssert.h#include #include PHtTr

19、ee haffmanAlgorithm(int m,EBTreeType* w)PHtTree pht;int i,j;int firstMinIndex,secondMinIndex;int firstMinW,secondMinW;pht=(PHtTree)malloc(sizeof(struct HtTree);assertF(pht!=NULL,in haffman algorithm,mem apply failuren);/*Initialize the tree array*/for(i=0;ihti.llinkIndex=-1;pht-hti.rlinkIndex=-1;pht

20、-hti.parentIndex=-1;if(ihti.ww=wi;=(char)i;elsepht-hti.ww=-1;for(i=0;im-1;i+)/new Inner Node Num:m-1firstMinW=MAXCHAR;firstMinIndex=-1;secondMinW=MAXCHAR;secondMinIndex=-1;for(j=0;jhtj.wwhtj.parentIndex=-1) /trans minFirst info to minSecond infosecondMinIndex=firstMinIndex;secondMinW=fir

21、stMinW;/set new first min node.firstMinIndex=j;firstMinW=pht-htj.ww;else if(pht-htj.wwhtj.parentIndex=-1) secondMinW=pht-htj.ww;secondMinIndex=j;/Construct a new node. m+i is current new nodes indexpht-htfirstMinIndex.parentIndex=m+i;pht-htsecondMinIndex.parentIndex=m+i;pht-htm+i.ww=firstMinW+second

22、MinW;pht-htm+i.llinkIndex=firstMinIndex;pht-htm+i.rlinkIndex=secondMinIndex;pht-rootIndex=m+i;return pht;/*Invoke:preHaffListMake(myHtTree,myHtTree-rootIndex,0x00,0,myList)*/void preHaffListMake(PHtTree inTree,int rootIndex,unsigned long youBiao,int sDepth,HaffCode* inList)if(inTree-htrootIndex.llin

23、kIndex=-1&inTree-htrootIndex.rlinkIndex=-1)inListinTree-htrootI.haffCode=youBiao;inListinTree-htrootI.haffCodeLen=sDepth;elsepreHaffListMake(inTree,inTree-htrootIndex.llinkIndex,youBiaohtrootIndex.rlinkIndex,(youBiao1)|0x01,sDepth+1,inList);MyAssert.c#include myAssert.h#include #include void assertF(int condition,char* errorMsg)if(!condition)printf(n%sn,errorMsg);abort();ECBTree.h#ifndef

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论