华北科技学院_《数据结构》_哈夫曼压缩_实验报告_第1页
华北科技学院_《数据结构》_哈夫曼压缩_实验报告_第2页
华北科技学院_《数据结构》_哈夫曼压缩_实验报告_第3页
华北科技学院_《数据结构》_哈夫曼压缩_实验报告_第4页
华北科技学院_《数据结构》_哈夫曼压缩_实验报告_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

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

文档简介

1、华北科技学院计算机系综合性实验实 验 报 告 课程名称 数据结构实验 实验学期 2011 至 2012 学年 第 一 学期学生所在系部 计算机学院 年级 专业班级 学生姓名 学号 任课教师 鞠宏军 实验成绩 计算机系制实验报告须知1、 学生上交实验报告时,必须为打印稿(A4纸)。页面空间不够,可以顺延。2、 学生应该填写的内容包括:封面相关栏目、实验地点、时间、目的、设备环境、内容、结果及分析等。3、 教师应该填写的内容包括:实验成绩、教师评价等。4、 教师根据本课程的实验指导中实验内容的要求,评定学生的设计性实验成绩;要求在该课程期末考试前将实验报告交给任课教师。设计性实验中,所涉及的程序,

2、文档等在交实验报告前,拷贝给任课教师。任课教师统一刻录成光盘,与该课程的期末考试成绩一同上交到系里存档。5、 未尽事宜,请参考该课程的实验大纲和教学大纲。数据结构(C语言)实验报告专业:计算机科学与技术地点:基础实验室五一、 实验题目:用哈夫曼编码实现文件压缩。二、实验目的:1、了解文件的概念。2、掌握线性链表的插入、删除等算法。3、掌握Huffman树的概念及构造方法。4、掌握二叉树的存储结构及遍历算法。5、利用Huffman树及Huffman编码,掌握实现文件压缩的一般原理。三、实验设备与环境:微型计算机、Windows 系列操作系统 、Visual C+6.0软件四、实验内容:根据asc

3、ii码文件中各ascii字符出现的频率情况创建Haffman树,再将各字符对应的哈夫曼编码写入文件中,实现文件压缩。五、概要设计:本次实验将文件中的字符作为结点,每个字符在文件中出现的频率作为结点的权值,采用Huffman算法构造Huffman树,将字符用尽可能短的二进制数位表示(频率越低,二进制数位越长),而不是用8位的ASCII码进行存储,已达到节省存储空间,压缩文件的目的。程序设计的步骤如下:统计需压缩文件中每个字符出现的频率。将每个字符出现的频率作为叶子结点构建Huffman树,然后将树中结点引向其左孩子的分支标“0”,引向其右孩子的分支标“1”;每个字符的编码即为从根到每个叶子的路径

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

5、哈夫曼树。(2)Huffman编码:数据通信用的二进制编码思想:根据字符出现频率编码,使电文总长最短编码:根据字符出现频率构造Huffman树,然后将树中结点引向其左孩子的分支标“0”,引向其右孩子的分支标“1”;每个字符的编码即为从根到每个叶子的路径上得到的0、1序列。(3)二叉树的存储结构 typedef struct node datatype data; struct node *lchild, *rchild;BinTree;压缩过程的实现的流程图如下:压缩过程的实现:(1)分为:创建Haffman树à打开需压缩文件à将需压缩文件中的每个ascii码对应的haff

6、man编码按bit单位输出à文件压缩结束。(2其中,步骤和步骤是压缩过程的关键。1) 步骤1:这里所要做工作是得到Haffman数中各叶子结点字符出现的频率并进行创建。统计字符出现的频率可以有很多方法:如每次创建前扫描被创建的文件,“实时”的生成各字符的出现频率;或者是创建前即做好统计。本文采用后一种的方案,统计了十篇不同的文章中字符出现的频率。当前,也可以根据被压缩文件的特性有针对性的进行统计,如要压缩C语言的源文件,则可事先对多篇C语言源文件中出现的字符进行统计,这样,会创建出高度相对较“矮”的Haffman树,从而提高压缩效果。2) 步骤3: 将需压缩文件中的每个ascii码对

7、应的haffman编码按bit单位输出,这是本压缩程序中最关键的部分。(3)这里涉及“转换”和“输出”两个关键步骤:“转换”部分大可不必去通过遍历Haffman树来找到每个字符对应的哈夫曼编码,可以将每个Haffman码值及其对应的ascii码存放于如下所示的结构体中:七、Code.c核心代码:Code.c#include "ECBTree.h"#include "MyAssert.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#define LEN

8、GTH 128#define DEBUG 1#define 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 h

9、affListLENGTH; PHtTree myHtTree; /声明哈弗曼树机构体 char inputFileNameLENGTH,outputFileNameLENGTH; /定义字符串数组 用于存放 接受和输出文件名 FILE* inputFile,* outputFile,* keyFile; int fileNameLen; char inData,outputData; unsigned long curCode,tmpBinData; int curLen,realLen,curIndex; int i; int count; unsigned long rearCode;

10、/用作后方的数据参考 int rearCodeLen; if (argc<=1) /判断程序运行时是否附带文件路径参数 printf("please enter your file address.n"); return; else strcpy(inputFileName,argv1); /拷贝输入输出文件 文件的路径 strcpy(outputFileName,argv1); fileNameLen=strlen(argv1); /文件路径名长度 outputFileNamefileNameLen-4='0' /重命名输出文件名 strcat(ou

11、tputFileName,dotRer); /将.txt替换为.rer inputFileNamefileNameLen='0' outputFileNamefileNameLen+4='0' if(inputFile=fopen(inputFileName,"rb")=NULL) /打开要压缩的文件 printf("file path not foundn"); return; if (DEBUG) printf("input file open successn"); /打开成功提示 assertF

12、(outputFile=fopen(outputFileName,"wb")!=NULL,"output file error"); /打开创建输出文件 if (DEBUG) printf("output file open successn"); /打开或者创建成功提示 if(keyFile=fopen("KEY.txt","rb")=NULL) /打开字符出现的频率(即权值)key.txt文件 printf(">-keyFile not founded-<n"

13、); /打开失败提示 return; for(i=0;i<LENGTH-1;i+) /读取字符出现的频率(即权值)key.txt文件放到wList数组中 fscanf(keyFile,"%d,",&wListi); fscanf(keyFile,"%d;",&wListi); myHtTree=haffmanAlgorithm(LENGTH,wList); /建立赫夫曼树 for(i=0;i<LENGTH;i+) /字符的hafflist对应编码 haffListi.asciiCode=(char)i; preHaffList

14、Make(myHtTree,myHtTree->rootIndex,0x000000,0,haffList); /根据预先设置的不同字符的权重,得到128个ASCII码对应的赫夫曼编码 fprintf(stdout,"haffCode List:rn"); for(i=0;i<LENGTH-1;i+) /输出对应的128个ASCII码对应的赫夫曼编码 fprintf(stdout,"%d,",haffListi.haffCode); fprintf(stdout,"%drn",haffListi.haffCode); fp

15、rintf(stdout,"haffCode List Len:rn"); for(i=0;i<LENGTH-1;i+) /输出每个字符对应的赫夫曼编码的长度 fprintf(stdout,"%d,",haffListi.haffCodeLen); fprintf(stdout,"%drn",haffListi.haffCodeLen); if(DEBUG) printf("ntest start.n"); /开始处理输入文件,并写入输出文件 curIndex=curLen=0; rearCode=haffL

16、istREARPOS.haffCode; rearCodeLen=haffListREARPOS.haffCodeLen; while(!feof(inputFile) /读取文件,知道读取所以字符后结束 count=0; outputData=0x01; while(count<8) if(curIndex=curLen) /1.get data. if(feof(inputFile) break; inData=fgetc(inputFile); /读取文件中得字符返回给inData if(inData=-1&&feof(inputFile) if(count=0)

17、outputData=-1; else /对后面的输出调整 for(i=0;i<8-count;i+) outputData<<=1; outputData|=(rearCode>>(rearCodeLen-1-i)&0x01); break; curCode=haffListinData.haffCode; /获取inData对应的编码 curLen=haffListinData.haffCodeLen; realLen=getBinLen(curCode); i=curLen-realLen; curIndex=0; if(i>0) output

18、Data<<=1; /不需要位数据 i-; else tmpBinData=(curCode>>(curLen-curIndex-1)&0x01; outputData<<=1; outputData|=(char)tmpBinData; /*-*/ curIndex+; count+; fputc(outputData,outputFile); /输出压缩后的数据到outputFile对应文件中 if(DEBUG) printf("ntest ends.n"); fclose(inputFile); /关闭输入文件 fclose

19、(outputFile); /关闭输出文件 getchar(); return;EBCTree.c#include "ECBTree.h"#include "MyAssert.h"#include <stdio.h>#include <stdlib.h>PHtTree haffmanAlgorithm(int m,EBTreeType* w) PHtTree pht; int i,j; int firstMinIndex,secondMinIndex; int firstMinW,secondMinW; pht=(PHtTree)

20、malloc(sizeof(struct HtTree); assertF(pht!=NULL,"in haffman algorithm,mem apply failuren"); for(i=0;i<2*m-1;i+)/初始化哈弗曼树 pht->hti.llinkIndex=-1; pht->hti.rlinkIndex=-1; pht->hti.parentIndex=-1; if(i<m) pht->hti.ww=wi; pht->=(char)i; else pht->hti.ww=-1; for(i

21、=0;i<m-1;i+)/新的内部节点:M - 1 firstMinW=MAXCHAR; firstMinIndex=-1; secondMinW=MAXCHAR; secondMinIndex=-1; for(j=0;j<m+i;j+) if(pht->htj.ww<firstMinW&&pht->htj.parentIndex=-1) /将minFirst复制给minSecond secondMinIndex=firstMinIndex; secondMinW=firstMinW; /设置新的第一个分节点。 firstMinIndex=j; f

22、irstMinW=pht->htj.ww; else if(pht->htj.ww<secondMinW&&pht->htj.parentIndex=-1) secondMinW=pht->htj.ww; secondMinIndex=j; /构造一个新的节点。M + i是当前新的节点的索引 pht->htfirstMinIndex.parentIndex=m+i; pht->htsecondMinIndex.parentIndex=m+i; pht->htm+i.ww=firstMinW+secondMinW; pht->htm+i.llinkIndex=firstMinIndex; pht->htm+i.rlinkIndex=secondMinIndex; pht->rootIndex=m+i; return pht;void preHaffListMake(PHtTree inTree,int rootIndex,unsigned long youBiao,int sDepth,HaffCode* inL

温馨提示

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

评论

0/150

提交评论