哈夫曼树的构造和应用.docx
《哈夫曼树的构造和应用.docx》由会员分享,可在线阅读,更多相关《哈夫曼树的构造和应用.docx(10页珍藏版)》请在冰豆网上搜索。
哈夫曼树的构造和应用
《计算机软件技术基础》实验报告
实验名称:
实验三哈夫曼树的应用和实现
实验目的:
掌握哈夫曼树的基本构造,并能运用哈夫曼树实现前缀编码。
实验内容:
完成下述功能:
(1)根据输入的字符和相应的权重建立哈夫曼树,并输出已经建立的相应内容作为检查;
(2)运用哈夫曼树实现前缀编码,并输出各字符的编码串;
(3)输入一组二进制报文,进行译码,并输出译文。
实验要求:
(1)数据元素为字符,其相应的权值为float;
(2)对实验内容进行算法设计,将编制的程序输入计算机,编译运行;
(3)程序的实际功能与上述所列功能不完全相符,调试程序,找出问题所在,并纠正。
(4)以教材中P162的例为数据,验证结果,并给出相应的说明。
实验原理:
哈夫曼树的构造和应用(流程图)。
1,建立哈夫曼树
2,构建哈夫曼编码表
3,译码过程是编码的逆过程,算法流程图此处省略。
编译环境:
PC中C++
实验调试及分析处理:
1,实验调试过程中出现以下错误:
分析处理:
程序运行出现上述错误,调试很久后发现,此问题主要是在调用译码函数时出错,原因是译码函数与主函数之间数据传递出现问题,修改后问题得到解决。
2,实验调试过程中出现以下错误:
分析处理:
程序运行出现上述错误,明显与书本上的例题运行结果不一致,程序也没发现什么大的错误,与同学讨论后发现原因,if(ht[j].parent==0&&m1>ht[j].weight)
{m2=m1;k2=k1;
m1=ht[j].weight;k1=j;
}
else
if(ht[j].parent==0&&m2>ht[j].weight)
这段程序应该改成if(ht[j].parent==0&&(m1-ht[j].weight)>=0.000001)
{m2=m1;k2=k1;
m1=ht[j].weight;k1=j;
}
else
if(ht[j].parent==0&&(m2-ht[j].weight)>=0.000001)。
改完以后运行结果与课本一致。
3,实验调试过程中出现以下错误:
分析处理:
程序运行中出现错误,主要是未理解scanf函数的应用,输入时若是一串二进制数字相邻输入,会当成一个数字读入,导致出错,修改输入方式后,再次运行这个错误消除。
实验结果:
1,哈夫曼树的构造,并输出已经建立的相应内容作为检查;
2,运用哈夫曼树实现前缀编码,并输出各字符的编码串
3.输入一组二进制报文,进行译码,并输出译文。
实验结果分析及总结
这次实验的收获主要是对哈夫曼树的结构有了更深入的理解,以及利用哈夫曼树的前缀编码,这是本课程的重点,应该注重学习。
本次实验结果基本正确,能完全实现实验要求的功能,但也存在不足的地方,如运行界面不美观,程序语句不精练,有些地方可以更加简单等等。
这些都需要我在以后的实验中着重注意并加以学习,另外,这次实验编程个人所花时间较长,这说明我对知识点不够熟悉,掌握程度不够,在今后的学习中应该更加严谨,虚心向同学学习,不懂的地方应该先自己理解再交流。
参考资料:
《计算机软件技术基础教程》,刘彦明;《C语言设计》。
附:
实验三哈夫曼树的应用和实现源程序。
#include"stdio.h"
#definemaxbit10/*定义哈夫曼编码最大长度*/
#definemaxvalue10000/*定义最大权值常量*/
#definemaxnodenumber100/*定义结点最大数目常量*/
typedefstruct/*定义结点结构*/
{floatweight;
chardata;
intparent,lchild,rchild;
}htnode;
typedefstruct/*定义保存一个叶子结点哈曼编码的结构*/
{intbit[maxbit];
intstart;
}hcodetype;
hcodetypecd[maxbit];
voidmain()/*主函数*/
{voidhuffmancode(htnodeht[],intn);
voidhuffmandecode(hcodetypecd[],htnodeht[],intn);
htnodeht[maxnodenumber];
inti,j,k1,k2,n,a;
floatm1,m2;
printf("哈夫曼树的构造及应用\n");
printf("请输入叶子数目n:
");/*提示输出叶子结点个数*/
scanf("%d",&n);
printf("Pleaseinputdataandweight:
\n");/*提示输出各叶子结点的权值*/
for(i=0;i<2*n-1;i++)
{ht[i].weight=0.00000;
ht[i].data='0';
ht[i].parent=0;
ht[i].lchild=0;
ht[i].rchild=0;
}
for(i=0;i{fflush(stdin);
scanf("%c%f",&ht[i].data,&ht[i].weight);}
for(i=0;i{m1=maxvalue;
m2=maxvalue;
k1=0;k2=0;
for(j=0;jif(ht[j].parent==0&&(m1-ht[j].weight)>=0.000001)
{m2=m1;k2=k1;
m1=ht[j].weight;k1=j;
}
else
if(ht[j].parent==0&&(m2-ht[j].weight)>=0.000001)
{m2=ht[j].weight;k2=j;
}
ht[k1].parent=n+i;
ht[k2].parent=n+i;
ht[n+i].weight=ht[k1].weight+ht[k2].weight;
ht[n+i].lchild=k1;
ht[n+i].rchild=k2;
}
printf("\n构造的哈夫曼树如下:
\n");
printf("\n");
printf("数组下标lchilddataweightrchlidparent\n");
for(i=0;i<2*n-1;i++){
printf("%d%d%c%f%d%d\n",i,ht[i].lchild,ht[i].data,ht[i].weight,ht[i].rchild,ht[i].parent);
}
printf("Thedataandthebitsisasfollows:
\n");
huffmancode(ht,n);/*调用函数*/
printf("请输入一组需要译码的二进制报文(单个数字之间请用空格隔开,如1011应该输入1011,以-1结尾):
\n");
huffmandecode(cd,ht,n);/*调用函数*/
}
voidhuffmancode(htnodeht[],intn)/*对具有n个叶子结点的哈夫曼树ht,求所有叶子结点的哈夫曼编码并输出*/
{inti,j,c,p,m,k;
charch[100];
hcodetypecd[100];
for(i=0;i{c=i;j=maxbit;
do
{j--;
p=ht[c].parent;
if(ht[p].lchild==c)
cd[i].bit[j]=0;
else
cd[i].bit[j]=1;
c=p;
}while(p!
=0);
cd[i].start=++j;
}
for(i=0;i{printf("data:
%cbits:
",ht[i].data);
for(j=cd[i].start;jprintf("%d",cd[i].bit[j]);
printf("\n");
}
}
voidhuffmandecode(hcodetypecd[],htnodeht[],intn)
{inti,c,p,b;
intendflag=-1;
i=2*n-2;
scanf("%d",&b);
printf("译码的结果如下:
\n");
while(b!
=endflag)
{if(b==0)i=ht[i].lchild;
elsei=ht[i].rchild;
if(ht[i].lchild==0)
{printf("%c",ht[i].data);
i=2*n-2;
}
scanf("%d",&b);
}
printf("\n");
if((ht[i].lchild!
=0)&&(i!
=2*n-2))
printf("\nERROR\n");
}