树的应用哈夫曼编编码 和 译码.docx
- 文档编号:28200685
- 上传时间:2023-07-09
- 格式:DOCX
- 页数:14
- 大小:39.69KB
树的应用哈夫曼编编码 和 译码.docx
《树的应用哈夫曼编编码 和 译码.docx》由会员分享,可在线阅读,更多相关《树的应用哈夫曼编编码 和 译码.docx(14页珍藏版)》请在冰豆网上搜索。
树的应用哈夫曼编编码和译码
华%%%%%%%%%%%%%%%%%%学院数据结构实验报告
2011~2012学年第二学期2011级计算机专业
班级:
学号:
姓名:
实验三树的应用
一、实验题目:
树的应用——哈夫曼编/译码
二、实验内容:
利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。
根据哈夫曼编码的原理,编写一个程序,在用户输入字符及权值的基础上求哈夫曼编码。
要求:
(1)从键盘输入字符集(字母a~z,空格)共27个字符,以及出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树,并输出数组ht[]的初态和终态。
(2)对各个字符进行哈夫曼编码,打印输出字符及对应的哈夫曼编码。
(3)编码:
从键盘输入字符串,利用已建好的哈夫曼编码,实现该字符串的编码。
(4)(选作)译码:
从键盘输入二进制串,利用已建好的哈夫曼编码,将二进制串还原为字符串。
三、程序源代码:
typedefstruct
{
chardata;
intweight;
intparent;
intlchild;
intrchild;
}HTNode;
typedefstruct
{
charcd[100];
intstart;
}HCode;
//这里保存字母对应的编码,我本来想用指向字符数组的指针数组,可是后来想到利用结构体更简单。
structCodes
{
charch;
charcodes[27];
};
#include
#include
#include
constintmaxsize=100;
//特色,动态编码
voidtongji(charstr[],int*pinlv);
voidcreateHT(HTNode*ht,intn,intpinlv[]);
voidshowHT(HTNodeht[],intn);
voidcreateHcode(HTNodeht[],HCode*hcd,intn);
voidshowHCode(HCodehcd[],intn,intpinlv[]);
//使字符与编码对应
voidmatchcodes(HCodehcd[],intpinlv[],intn,Codes*code);
voidcharToCode(Codescodes[],char*str);
voidcodeToChar(Codescodes[]);
voidmain()
{
cout<<"本例实现动态编码:
根据输入的字符串建立编码规则,然后按此规则对输入的字符串进行编码,对输入的编码进行译码操作"< //输入 cout<<"inputastring"< charstr[maxsize]; gets(str); //统计 intpinlv[27]; intlen=0; for(inti=0;i<27;i++) pinlv[i]=0; tongji(str,pinlv); for(intk=0;k<27;k++) if(pinlv[k]! =0) len++; cout< //cout< //构造哈夫曼树 HTNodeht[199]; createHT(ht,len,pinlv); //哈夫曼编码 HCodehcd[27]; createHcode(ht,hcd,len); showHCode(hcd,len,pinlv); //字符与编码对应匹配 Codescodes[27]; matchcodes(hcd,pinlv,len,codes); //chartocode charToCode(codes,str); //codetochar codeToChar(codes); } //这个函数有错误,已经改正 voidcodeToChar(Codescodes[]) { cout<<"根据上面输出的编码规则,请输入要译码的01编码(相邻编码要以逗号分割,以“#”结束)"< charstr[100]; gets(str); cout< "< chartemp[27];//保存每个字符的编码,每次要赋0啊 inti,j; for(i=0,j=0;i<100;i++) { if(str[i]! =',') { temp[j]=str[i]; j++; } else { temp[j]='\0'; for(intk=0;k<27;k++) { if(strcmp(codes[k].codes,temp)==0) { cout< //cout.flush(); break; } } j=0;//赋0操作 } if(str[i]=='#') { break; } } cout< } voidcharToCode(Codescodes[],char*str) { charch=*str; intk=0; cout< "< while(ch! ='\0') { for(inti=0;i<27;i++) { if(codes[i].ch==ch) cout< } k++; ch=*(str+k); } cout< } //已经改进过的地方 voidmatchcodes(HCodehcd[],intpinlv[],intn,Codes*codes) { inti,k,m; charch='a'; intp=0; chartemp[27]; for(intz=0;z<26;z++) { temp[z]=''; } temp[26]='\0'; for(i=0;i<27;i++) { if(pinlv[i]! =0) { ch='a'; ch=char(ch+i); if(ch>='a'&&ch<='z') { codes[p].ch=ch; //测试 /*if(codes[p].ch==ch) { cout<<"succss"< }*/ } else codes[p].ch=''; m=0; for(k=hcd[p].start;k<=n;k++) { temp[m]=hcd[p].cd[k]; m++; } //字符串必须给出结束符位置,否则会输出乱码啊 temp[m]='\0'; //codes[p]=temp; strcpy(codes[p].codes,temp); //cout< //cout< p++; } } } voidshowHCode(HCodehcd[],intn,intpinlv[]) { inti,k; charch='a'; intp=0; cout<<"字符"<<""<<"对应编码"< for(i=0;i<27;i++) { //每次必须从字符'a'开始 ch='a'; //// ch=char(ch+i); if(pinlv[i]! =0) { if(ch>='a'&&ch<='z') cout< else cout<<""<<""; for(k=hcd[p].start;k<=n;k++) cout< p++; cout< } } } voidcreateHcode(HTNodeht[],HCode*hcd,intn) { inti,f,c; HCodehc; for(i=0;i { //不是书上的hc.start=n; hc.start=n-1; c=i; f=ht[i].parent; while(f! =-1) { if(ht[f].lchild==c) hc.cd[hc.start--]='0'; else hc.cd[hc.start--]='1'; c=f; f=ht[f].parent; } //最后一位必须赋值为结束符 hc.cd[n]='\0'; hc.start++; hcd[i]=hc; } } voidcreateHT(HTNode*ht,intn,intpinlv[]) { for(intm=0;m<=2*n-1;m++)//初始化节点的所有与域值 ht[m].parent=ht[m].lchild=ht[m].rchild=-1; charch='a'; intp=0; for(intz=0;z<27;z++)//循环27个字母(a-z和''),若频数大于0,就创建节点 { if(pinlv[z]! =0) { if(ch>='a'&&'z'>=ch) { ht[p].data=ch; ht[p].weight=pinlv[ch-97]; } else { ht[p].data=''; ht[p].weight=pinlv[26]; } p++; } ch=char(ch+1); } cout<<"ht[]初态输出"; showHT(ht,n); inti,k,lnode,rnode; intmin1,min2; for(i=n;i<2*n-1;i++) { min1=min2=32767; lnode=rnode=-1; for(k=0;k<=i-1;k++) { if(ht[k].parent==-1) { if(ht[k].weight { min2=min1;rnode=lnode; min1=ht[k].weight;lnode=k; } elseif(ht[k].weight { min2=ht[k].weight; rnode=k; } } } ht[lnode].parent=i;ht[rnode].parent=i; ht[i].weight=ht[lnode].weight+ht[rnode].weight; ht[i].lchild=lnode;ht[i].rchild=rnode; ht[i].data='*'; } cout<<"ht[]终态输出"; showHT(ht,2*n-1); } voidtongji(charstr[],int*pinlv) { charch=*str; intk=1; while(ch! ='\0') {if(ch>='a'&&'z'>=ch) pinlv[ch-97]+=1; else pinlv[26]+=1; ch=*(str+k); k++; } } voidshowHT(HTNodeht[],intn) {cout<<"节点信息如下: "< cout<<"data"<<""<<"weig"<<""<<"pare"<<""<<"lchd"<<""<<"rchd"< for(inti=0;i { cout< } } 四、测试结果: 五、小结(包括收获、心得体会、存在的问题及解决问题的方法、建议等) 注: 内容一律使用宋体五号字,单倍行间距 通过本次实验,我感觉到自己的程序编程细节问题必须注意: 如使用gets()函数可接收带有空格的输入字符串;在进行编码译码时,必须注意,数组的上下界问题。 做一个程序,不仅要有思路,更要有细心,耐心。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 树的应用 哈夫曼编编码 译码 应用 哈夫曼编 编码