哈夫曼编码算法实现完整版讲课讲稿.docx
《哈夫曼编码算法实现完整版讲课讲稿.docx》由会员分享,可在线阅读,更多相关《哈夫曼编码算法实现完整版讲课讲稿.docx(9页珍藏版)》请在冰豆网上搜索。
![哈夫曼编码算法实现完整版讲课讲稿.docx](https://file1.bdocx.com/fileroot1/2022-12/6/33cc9b51-ee26-44bb-b60c-223f7a196545/33cc9b51-ee26-44bb-b60c-223f7a1965451.gif)
哈夫曼编码算法实现完整版讲课讲稿
哈夫曼编码算法实现完整版
实验三树的应用
一.实验题目:
树的应用——哈夫曼编码
二.实验内容:
利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。
根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求哈夫曼编码。
要求:
从键盘输入若干字符及每个字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树,然后对各个字符进行哈夫曼编码,最后打印输出字符及对应的哈夫曼编码。
三、程序源代码:
#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()来解决,但是还不是很理想。
为了察看方便,把有些文件的内容直接显示在终端上了,没有列出生成的文件里的结果。
图一