哈夫曼编码算法实现完整版.docx
- 文档编号:5714282
- 上传时间:2022-12-31
- 格式:DOCX
- 页数:9
- 大小:50.98KB
哈夫曼编码算法实现完整版.docx
《哈夫曼编码算法实现完整版.docx》由会员分享,可在线阅读,更多相关《哈夫曼编码算法实现完整版.docx(9页珍藏版)》请在冰豆网上搜索。
哈夫曼编码算法实现完整版
实验三树的应用
一.实验题目:
树的应用——哈夫曼编码
二.实验内容:
利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。
根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求哈夫曼编码。
要求:
从键盘输入若干字符及每个字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树,然后对各个字符进行哈夫曼编码,最后打印输出字符及对应的哈夫曼编码。
三、程序源代码:
#include
#include
#include
#include
typedefstruct{
chardata;
intweight;
intparent,lchild,rchild;
}HTNode,*HuffmanTree;
typedefchar**HuffmanCode;
voidSelect(HuffmanTree&HT,intn,intm)
{HuffmanTreep=HT;
inttmp;
for(intj=n+1;j<=m;j++)
{inttag1,tag2,s1,s2;
tag1=tag2=32767;
for(intx=1;x<=j-1;x++)
{if(p[x].parent==0&&p[x].weight {tag1=p[x].weight;s1=x;} } for(inty=1;y<=j-1;y++) {if(p[y].parent==0&&y! =s1&&p[y].weight {tag2=p[y].weight;s2=y;} } if(s1>s2)//将选出的两个节点中的序号较小的始终赋给s1 {tmp=s1;s1=s2;s2=tmp;} p[s1].parent=j; p[s2].parent=j; p[j].lchild=s1; p[j].rchild=s2; p[j].weight=p[s1].weight+p[s2].weight; } } voidHuffmanCoding(HuffmanTree&HT,intn,char*w1,int*w2) { intm=2*n-1; if(n<=1)return; HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); HuffmanTreep=HT; for(inti=1;i<=n;i++) {p[i].data=w1[i-1]; p[i].weight=w2[i]; p[i].parent=p[i].lchild=p[i].rchild=0; } for(;i<=m;i++) {p[i].weight=p[i].parent=p[i].lchild=p[i].rchild=0;} Select(HT,n,m); ofstreamoutfile;//生成hfmTree文件 outfile.open("hfmTree.txt",ios: : out); for(i=1;i<=m;i++) {outfile< <<"\t"< } outfile.close(); cout<<"初始化结果已保存在hfmTree文件中\n"; } voidToBeTree()//将正文写入文件ToBeTree中 { ofstreamoutfile; outfile.open("ToBeTree.txt",ios: : out); outfile<<"THISPROGRAMISMYFAVORITE"; outfile.close(); } voidEncoding(HuffmanTree&HT,intn)//编码 { HuffmanCodeHC; HC=(HuffmanCode)malloc((n+1)*sizeof(char*)); char*cd; cd=(char*)malloc(n*sizeof(char)); cd[n-1]='\0'; for(intk=1;k<=n;k++) {intstart=n-1; for(intc=k,f=HT[k].parent;f! =0;c=f,f=HT[f].parent) {if(HT[f].lchild==c)cd[--start]='0'; elsecd[--start]='1'; } HC[k]=(char*)malloc((n-start)*sizeof(char)); strcpy(HC[k],&cd[start]); } cout<<"输出哈夫曼编码: "< for(inth=1;h<=n;h++)//输出编码 {cout< "; cout< cout<<""; if(h%8==0)cout< } cout< "< ToBeTree(); //读取TOBETREE文件里的正文,并进行编码 fstreaminfile; infile.open("ToBeTree.txt",ios: : in); chars[80]; while(! infile.eof()) {infile.getline(s,sizeof(s));} infile.close(); fstreamoutfile; outfile.open("CodeFile.txt",ios: : out); intcount=0; for(h=0;s[h]! ='\0';h++) {for(k=1;k<=n;k++) if(s[h]==HT[k].data) {cout< cout<<""; count++; outfile< break; } if(count%9==0)cout< } outfile.close(); cout<<"\n编码结果已保存在文件CodeFile中."; cout< } voidDecoding(HuffmanTree&HT,intn)//译码 { intf=2*n-1; fstreaminfile; infile.open("CodeFile.txt",ios: : in); chars[1000]; while(! infile.eof()) {infile.getline(s,sizeof(s));} infile.close(); inti=0; intj=0; fstreamoutfile; outfile.open("TextFile.txt",ios: : out); while(s[i]! ='\0') {f=2*n-1; while(HT[f].lchild! =0)//以f对应的节点的左孩子的值==0作为结束 {if(s[j]=='0')f=HT[f].lchild; elsef=HT[f].rchild; j++; } i=j; cout< outfile< } outfile.close(); cout<<"\n译码结果已保存在文件TextFile中."; cout< } voidPrint()//印代码文件 {intcount=0; fstreaminfile; infile.open("CodeFile.txt",ios: : in); chars[1000]; while(! infile.eof()) {infile.getline(s,sizeof(s)); for(inti=0;s[i]! ='\0';i++) {cout< count++; if(count%50==0)cout< } } infile.close(); cout< } charmenu()//菜单函数 {cout<<"功能菜单如下: "< cout<<"*********************"< cout<<"I: 初始化(Initialization)"< cout<<"E: 编码(Encoding)"< cout<<"D: 译码(Decoding)"< cout<<"P: 印代码文件(Print)"< cout<<"Q: 退出(Exit)"< cout<<"*********************"< cout<<"请输入功能字符: "; charch; cin>>ch; returnch; } voidmain() {intn; intArray[100]; charcArray[100]; HuffmanTreeHT; cout<<"输入n个字符: "; cin.getline(cArray,100); n=strlen(cArray); cout<<"一共"< cout<<"依次输入各个字符的权值: "< for(inti=1;i<=n;i++)cin>>Array[i]; inttag; charx=menu(); while (1) {switch(x) { case'I': HuffmanCoding(HT,n,cArray,Array);break; case'E': Encoding(HT,n);break; case'D': Decoding(HT,n);break; case'P': Print();break; case'Q': tag=0;cout<<"结束"< default: cout<<"你输入错误! "< } if(tag==0)break; cout<<"y(继续)orn(退出)"< charch; cin>>ch; if(ch=='y') {cout<<"请输入功能字符: "; charc; cin>>c; x=c; } elseexit (1); } } 测试数据: 用下表给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的译码和编码: "THISPROGRAMISMYFAVORITE". 字符空格ABCDEFGHIJKLM 频度1866413223210321154757153220 字符NOPQRSTUVWXYZ 频度5763151485180238181161 四.测试结果: 如图一所示 五.实验体会 通过本次实验,尤其在自己对程序的调试过程中,感觉对树的存储结构,终结状态,还有编码,译码的过程都有了比较清晰的认识。 在做本次实验时,其他的都没什么问题,以前很少进行文件操作,刚开始有点手生,但是在实验作完后,文件操作已经用的比较熟练了。 最近几次实验,感到自己对本题实验的运行机理和过程掌握的最为透彻。 收获不小。 在实验过程中,遇到的一个主要问题是在C++里面输入单个空格字符的问题。 最终通过用cin.getline()来解决,但是还不是很理想。 为了察看方便,把有些文件的内容直接显示在终端上了,没有列出生成的文件里的结果。 图一
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哈夫曼 编码 算法 实现 完整版