哈弗曼编译码器 罗忠霖.docx
- 文档编号:3312648
- 上传时间:2022-11-21
- 格式:DOCX
- 页数:15
- 大小:164.96KB
哈弗曼编译码器 罗忠霖.docx
《哈弗曼编译码器 罗忠霖.docx》由会员分享,可在线阅读,更多相关《哈弗曼编译码器 罗忠霖.docx(15页珍藏版)》请在冰豆网上搜索。
哈弗曼编译码器罗忠霖
《数据结构》实验报告
题目:
实验五哈夫曼编/译码器
学号:
72
成
绩
班级:
计算1013
日期:
2011.11.15
姓名:
罗忠霖
指导老师:
杨艳华
一、实验目的:
本次的实验目的在于使读者深入了解树的特性,以便在实际问题背景下灵活运用他们;同时还将巩固掌握对树结构的构造方法的理解,并且回顾文件操作的使用。
二、实验环境:
本次试验在VC++环境下调试。
三、实验内容与完成情况:
1.问题描述
利用哈夫曼编码进行通信可以大大提高信道利用率,缩短信息传输的时间,降低传输成本。
但是这要求在发送端通过一个编码系统对待传数据预先编码,在接收端将传来的数据进行译码。
对于双工信道,每端都需要一个完整的编/译码系统。
试为这样的信息收发站写一个哈夫曼码的编/译码系统。
2.基本要求
一个完整的系统应具有以下功能:
(1)初始化,构造哈弗曼树。
(2)编码。
(3)译码。
(4)印代码文件。
(5)印哈弗曼树。
3.程序代码
#include
#include
#include
#include
typedefstruct
{
charchr1;
intweight;
intparent,lchild,rchild;
}HTNode,*HuffmanTree;
typedefstruct
{
charchr;
intw1;
char*code;//编码
}Ch;//字符和对应的权值及编码
voidSelect(HuffmanTree&HT1,intj,int&s1,int&s2);
voidHuffmanCoding(HuffmanTree&HT,Ch*w,intn);//构造哈夫曼树HT
voidencoding(HuffmanTree&HT,Ch*ch,intn);//求每个字符的哈夫曼编码
voidEncoding(Ch*ch1,intn);//编码
voidDecoding(HuffmanTree&HT,intsum);//译码
voidcaidan();
voidPrintf();
voidmain()
{
FILE*p;
intchoice,n1,w2=1;
inti,flag=1,m;
charch;
HuffmanTreeHTr;
Ch*c;
caidan();
while(flag)
{
loop:
printf("\n*请选择(0-5):
");
scanf("%d",&choice);
switch(choice)
{
case1:
printf("请输入字符集大小n=");
scanf("%d",&n1);
c=(Ch*)malloc((n1+1)*sizeof(Ch));
flushall();
for(i=1;i<=n1;i++)
{
printf("请输入字符及其权值:
");
scanf("%c%d",&ch,&w2);
c[i].chr=ch;c[i].w1=w2;
flushall();
}
HuffmanCoding(HTr,c,n1);
encoding(HTr,c,n1);
break;
case2:
Encoding(c,n1);
break;
case3:
Decoding(HTr,n1);
break;
case4:
Printf();
break;
case5:
m=2*n1-1;
if((p=fopen("TreePrint.txt","w"))==NULL)
printf("Filecouldnotbeopened\n");
else
{
fprintf(p,"\n哈夫曼树的构造如下所示:
\n");
fprintf(p,"结点weightparentlchildrchild");
for(i=1;i<=m;i++)
{
fprintf(p,"\n%4d%8d%8d%8d%8d",i,HTr[i].weight,
HTr[i].parent,HTr[i].lchild,HTr[i].rchild);
}
}
fclose(p);
printf("\n哈夫曼树的构造如下所示:
\n");
printf("结点weightparentlchildrchild");
for(i=1;i<=m;i++)
{
printf("\n%4d%8d%8d%8d%8d",i,HTr[i].weight,
HTr[i].parent,HTr[i].lchild,HTr[i].rchild);
}
break;
case0:
flag=0;printf("你选择了推出程序,欢迎使用!
\n");break;
default:
gotoloop;
}
}
}
voidcaidan()
{printf("\n*****************哈夫曼编译器*****************\n");
printf("1.初始化\n");
printf("2.编码\n");
printf("3.译码\n");
printf("4.打印代码文件\n");
printf("5.打印哈夫曼树\n");
printf("6.退出系统\n");
printf("**********************************************\n");
}
voidSelect(HuffmanTree&HT1,intj,int&s1,int&s2)
{
//在HT[1...j]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2
inti=0,d=0,h;
for(i=j;i>=0;i--)
{
if(HT1[i].parent!
=0)//在双亲不为0的条件下
continue;
if(d==0)//用s1记录第一个双亲为0的元素所在的位置
{
s1=i;
d++;
}
elseif(d==1)//用s2记录第而个双亲为0的元素所在的位置
{
s2=i;
d++;
}
elseif(d==2)
{
if(HT1[s1].weight<=HT1[s2].weight)//s2用于存储最小值的位置
{
h=s1;
s1=s2;
s2=h;
}
if(HT1[i].weight s1=i; } } } voidHuffmanCoding(HuffmanTree&HT,Ch*w,intn) { //*w存放n个字符的权值(均>0),构造哈夫曼树HT FILE*p; inti,j,m,s1,s2; if(n<=1)return; m=2*n-1;//树的结点总数 HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元未用 for(i=1;i<=n;i++) {//初始化 HT[i].chr1=w[i].chr; HT[i].weight=w[i].w1;// HT[i].parent=0; HT[i].lchild=0; HT[i].rchild=0; } for(i=n+1;i<=m;i++) {//初始化 HT[i].weight=0; HT[i].parent=0; HT[i].lchild=0; HT[i].rchild=0; } for(i=n+1;i<=m;i++)//建哈夫曼树 { //在HT[1...i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2。 Select(HT,i-1,s1,s2); HT[s1].parent=i;HT[s2].parent=i; HT[i].lchild=s1;HT[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; } if((p=fopen("hfmTree.txt","w"))==NULL) printf("Filecouldnotbeopened\n"); else { fprintf(p,"\n哈夫曼树的构造如下所示: \n"); fprintf(p,"结点weightparentlchildrchild"); for(i=1;i<=m;i++) { fprintf(p,"\n%4d%8d%8d%8d%8d",i,HT[i].weight, HT[i].parent,HT[i].lchild,HT[i].rchild); } } fclose(p); } voidencoding(HuffmanTree&HT,Ch*ch,intn) {//---从叶子到根逆向求每个字符的哈夫曼编码--- inti,c,f,start;// char*cd; cd=(char*)malloc(n*sizeof(char));//分配求编码的工作空 cd[n-1]='\0';//编码结束符。 for(i=1;i<=n;++i)//逐个字符求哈夫曼编码 { start=n-1;//编码结束符位置 for(c=i,f=HT[i].parent;f! =0;c=f,f=HT[f].parent)//从叶子到根逆向求编码 { if(HT[f].lchild==c)cd[--start]='0'; elsecd[--start]='1'; } ch[i].code=(char*)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间 strcpy(ch[i].code,&cd[start]);//从cd复制编码(串)到code } free(cd);//释放工作空间 } voidEncoding(Ch*ch1,intn) //利用已经建立的哈弗曼树编码对输入的字符进行哈弗曼编码 { FILE*q1,*q2; //chara[100];//用于存放输入的字符 charnum[1000],c; char*p=num;//用于存放字符对应的哈弗曼编码 inti,j; if((q1=fopen("ToBeTran.txt","r"))==NULL) printf("Filecouldnotbeopened\n"); else { rewind(q1); while(! feof(q1))//依次判断字符的对应的哈弗曼编码 { c=fgetc(q1); for(j=1;j<=n;j++) { if(c==ch1[j].chr) { printf("%c: %s",ch1[j].chr,ch1[j].code); strcpy(p,ch1[j].code); p=p+strlen(ch1[j].code); break; }//如果找到就把对应的哈弗曼编码复制到字符数组num中 } } *p='\0'; printf("\n得到的编码是: \n"); for(i=0;num[i]! ='\0';i++)//输出字符对应的哈弗曼编码 { if(i==50)printf("\n");//当输出50个字符时,进行换行 printf("%c",num[i]); } printf("\n"); } fclose(q1); if((q2=fopen("CodeFile.txt","w"))==NULL) printf("Filecouldnotbeopened\n"); else { i=0; while(num[i]! ='\0') { if(i==50)fprintf(q2,"\n"); fprintf(q2,"%c",num[i++]); } fprintf(q2,"\n"); } fclose(q2); } voidDecoding(HuffmanTree&HT,intsum)//译码 { FILE*p; //charcode1[1000];//用于存放输入的密码 chara1[100],c;//用于存放翻译好的字符 intn=0,i=0,b=2*sum-1; if((p=fopen("CodeFile.txt","r+"))==NULL) printf("Filecouldnotbeopened\n"); else { while(! feof(p)) { c=fgetc(p); if(c=='0')b=HT[b].lchild;//当遇到0时指向哈弗曼树的左子树 if(c=='1')b=HT[b].rchild;//当遇到1时指向哈弗曼树的右子树 if(HT[b].lchild==0&&HT[b].rchild==0)//当左右子树均为空时表明已找到对应的字符 { a1[n++]=HT[b].chr1;b=2*sum-1;//将对应的字符放在数组a1中,并重新设置b的值继续翻译 } } a1[n]='\0'; i=0; while(a1[i]! ='\0')//输出翻译好的字符 { if(i==50)printf("\n"); printf("%c",a1[i++]); } printf("\n"); } fclose(p); if((p=fopen("TextFile.txt","w"))==NULL) printf("Filecouldnotbeopened\n"); else { i=0; fprintf(p,"得到的翻译结果是: \n"); while(a1[i]! ='\0') { if(i==50)fprintf(p,"\n"); fprintf(p,"%c",a1[i++]); } fprintf(p,"\n"); } fclose(p); } voidPrintf() { FILE*p; if((p=fopen("CodeFile.txt","r"))==NULL) printf("Filecouldnotbeopened\n"); else { printf("得到的编码是: \n"); while(! feof(p)) { inti=0; if(i==50)printf("\n");//当输出50个字符时,进行换行 printf("%c",fgetc(p)); i++; } printf("\n"); } fclose(p); } 4.结果显示: 四、实验小结及体会: 通过本实验能够更好掌握文件指针的操作运用,加深理解,运用它解决一些实际问题,且能教熟练掌握数的结构以及哈弗曼算法。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哈弗曼编译码器 罗忠霖 哈弗曼编 译码器