数据结构实验报告05.docx
- 文档编号:2894997
- 上传时间:2022-11-16
- 格式:DOCX
- 页数:16
- 大小:68.66KB
数据结构实验报告05.docx
《数据结构实验报告05.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告05.docx(16页珍藏版)》请在冰豆网上搜索。
数据结构实验报告05
《数据结构》实验报告
班级:
10011206姓名:
邹维韬学号:
2012302516E-mail:
396881328@日期:
2013.11.24
◎实验题目:
哈夫曼编/译码器
◎实验目的:
了解掌握哈夫曼二叉树的创建和哈夫曼编码算法
◎实验内容:
编写一个程序,将输入字符串压缩为哈夫曼编码,生成编码表并进行解码。
一、需求分析
本程序以含父节点哈夫曼树作为算法的基本数据结构,利用哈夫曼生成树算法,推导出哈夫曼编码表,然后根据编码表对电文进行编码处理。
译码方式采用哈夫曼树遍历的方式,得到权重(即可得到权重对应的字母),然后将译文输出存储。
程序提供两种输入形式供用户选择:
1.输入界面直接输入;2.文件输入。
程序同样有两种输出形式:
1.界面直接输出;2.文件输出。
测试数据
1.直接输入:
编码
用户输入:
HelloWolrd/回车
输出:
(首先将用户输入存入’文件1.txt’)
编码表为
H->010e->011l->10o->110/空格->000
W->001r->1110d->1111
编码结果为
010*********
(将编码结果存入’文件2’.txt)
解码
用户输入:
10110001/回车
输出:
(首先将用户输入存入’文件3.txt’)
解码结果
loW
(将解码结果存入’文件4.txt’)
用户输入:
1011000/回车(无法解码的非法输入)
输出:
输入编码非法!
程序错误!
2.文件输入
编码
输入提示:
请输入文件名
用户输入:
1.txt/回车
输出:
编码表为
H->010e->011l->10o->110/空格->000
W->001r->1110d->1111
编码结果为
010*********
(将编码结果存入’文件2’.txt)
用户输入:
abcdefg.txt/回车(不存在的文件名)
输出:
找不到文件!
程序错误!
解码
输入提示:
请输入编码文件名
用户输入:
1.txt/回车
输出:
解码结果
loW
(将解码结果存入’文件4.txt’)
程序的运行过程是:
1.按提示选择电文输入模式
2.成功输入则进行权值统计,构造哈夫曼树,然后逆序遍历得到编码表,并根据编码表将输入电文进行编码,最后将编码结果存入’文件2.txt’,输入失败则报错退出
3.按提示选择译文编码输入模式。
4.输入合法则通过哈夫曼树正序遍历得到译文,存入’文件4.txt’中,输入失败则报错退出。
5.询问用户是否继续在该编码表下进行译文,输入Y回到第3步,否则继续。
6.摧毁哈夫曼树,重新初始化一系列变量。
7.询问用户输入是否结束程序,输入Y结束程序,输入N则回到第1步。
二概要设计
哈夫曼编码译码算法要求使用带权重与父结点二叉树作为数据存储结构,输入方式有直接输入和文件输入。
由直接输入或者文件输入得到电文字符串Alice之后,对其进行权重统计,用两个共用下标的一维数组(一个int型,一个char型)储存权重统计结果。
(也可采用char+int型结构体数组)。
根据哈夫曼树生成算法,首先将树的各个子树(结点)赋予权值,然后从中取两个权值最小的无父的子树(结点)拼接到新结点上,删除原来的子树,将新子树(结点)放进树里,重复以上步骤直到只有一棵树。
将生成的二叉树的各个无孩子结点进行逆序遍历回根结点,可由回溯路线得到每个权重(字符)所对应的编码值,据此得到编码表输出。
根据编码表一一转化为哈夫曼编码密文Charlie。
译文算法也是通过哈夫曼树遍历来实现,由根节点开始,从左到右依次读密文Charlie,读到1,遍历指针指向右孩子,读到0则指向左孩子,重复以上步骤直到遍历到没有孩子的结点,则该结点权重所指示的字符即是原字符,这是结点指针重新回到根结点,继续读取字符重复以上步骤直到密文Charlie全部读完。
主程序包含哈夫曼二叉树的声明,电文输入函数、哈夫曼编码函数、编码密文输出储存函数、哈夫曼编码密文输入函数、哈夫曼解码函数、哈夫曼译码原文输出储存函数等。
为方便用户多次输入,主程序用循环结构重复执行,直到用户中止。
1.基本操作:
intGetTreeHead(HTree&HT,intn)
初始条件:
有n个含权重有效结点的哈夫曼树H存在
操作结果:
输出H的根结点下标
voidGetWeight(charAlice[],intW[],int&N,charcW[])
初始条件:
字符串数组Alice存在
操作结果:
对输入字符串进行字符统计与字符权重统计,字符存入cW[k],其对应权重存入W[k],有一一映射关系。
字符种数统计后存入整形N。
voidSelect(HTree&HT,intn,int&a,int&b)
初始条件:
哈夫曼树HT存在,且字符种数为n
操作结果:
得到两个权值最小的子树(结点)下标,分别存入a,b(其中ab则a、b值交换)
voidHuffmanCoding(HTree&HT,HCode&HC,int*w,intn,charcW[])
操作结果:
根据权重*w与对应字符cW生成哈夫曼树,并生成编码表,存入二维字符数组(或字符串数组)HCode
voidHuffmanDecoding(charCharlie[],charAlice[],HTree&HT,intn)
操作结果:
将密文Charlie依据n个有效含权重结点的哈夫曼树HT,解码成译文存入Alice中。
voidWriteTxt(FILE*fp,chars[],chara[])
操作结果:
将密文/译文字符串a[]写入新创建的,文件名为”s”的文件中。
2.本程序包含五个模块:
主程序模块:
含有判断和程序循环结构,调用以下几种函数达到哈夫曼编码/解码的目的。
哈夫曼二叉树的声明
电文输入函数
哈夫曼编码函数
编码密文输出储存函数
哈夫曼编码密文输入函数
哈夫曼解码函数
哈夫曼译码原文输出储存函数等
三详细设计
1.元素类型、结构类型:
定义:
//哈夫曼树与哈夫曼编码矩阵的定义
typedefstructtagHuffman{
unsignedintweight;
charcSign;
unsignedintparent,lchild,rchild;
}HNode,*HTree;
typedefchar**HCode;
//关于哈夫曼树的一些基本操作:
//选择函数,两次遍历寻找权重最小的两个结点
voidSelect(HTree&HT,intn,int&a,int&b){
inti;
a=0;
inttmp;
unsignedintmin=65535;
for(i=n;i>=1;i--){
if(HT[i].parent==0){
if(HT[i].weight min=HT[i].weight; a=i; } } } tmp=HT[a].weight; HT[a].weight=65535; min=65535; for(i=n;i>=1;i--){ if(HT[i].parent==0){ if(HT[i].weight min=HT[i].weight; b=i; } } } HT[a].weight=tmp; if(a>b){ tmp=b; b=a; a=tmp; } }// //得到哈夫曼树的根结点 intGetTreeHead(HTree&HT,intn){ inti; for(i=1;i<=2*n-1;i++){ if(HT[i].parent==0)returni; } return-1; }// (2)字符处理函数: //输入字符进行权重统计 voidGetWeight(charAlice[],intW[],int&N,charcW[]){ inti,p=0,k=0; intiCheck; do{ iCheck=0; for(i=0;i if(cW[i]==Alice[p]){ W[i]++; iCheck=1; break; } } if(iCheck==0){ cW[k]=Alice[p]; W[k]++; k++; } p++; }while(Alice[p]! ='\0'); N=k; }// (3)输入-输出-存储函数 //创建写入txt voidWriteTxt(FILE*fp,chars[],chara[]){ fp=fopen(s,"w+"); if(fp! =NULL){ fputs(a,fp); fclose(fp); printf("字符串已存入'%s'! \n",s); } else{ printf("无法创建%s\n",s); Error(); } } //输入Alice(发送方)电文字符串,存入文件1.txt voidInputAndFileWrite_1(charAlice[]){ FILE*fp=NULL; intiCheck; charfilename[100]; printf("--------请选择输入模式--------\n"); printf("1.直接输入\n2.文件输入\n"); scanf("%d",&iCheck); //输入部分 system("cls"); fflush(stdin); switch(iCheck){ case1: { printf("请输入需要编码的字符串\n_______________________________________________________________\n"); gets(Alice); WriteTxt(fp,"文件1.txt",Alice); break; } case2: { //文件写入部分 printf("请输入电文文件名: "); scanf("%s",&filename); fflush(stdin); fp=fopen(filename,"r+"); if(fp==NULL){ printf("找不到文件! \n"); Error(); } fgets(Alice,CodeLength,fp); break; } default: Error(); } }// //输出编码结果,并存入文件2.txt voidPrintAndFileWrite_2(HCode&HC,charAlice[],charCharlie[],intW[],charcW[],intn){ inti,k,m; FILE*fp=NULL; //输出部分 printf("_______________________________________________________________\n据此分析字频得到编码表\n_______________________________________________________________\n");
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验 报告 05