数据结构实验四报告.docx
- 文档编号:24028658
- 上传时间:2023-05-23
- 格式:DOCX
- 页数:19
- 大小:135.25KB
数据结构实验四报告.docx
《数据结构实验四报告.docx》由会员分享,可在线阅读,更多相关《数据结构实验四报告.docx(19页珍藏版)》请在冰豆网上搜索。
数据结构实验四报告
实验报告
实验四哈夫曼树及其的应用
一、实验目的
1.在二叉树基本操作的基础上,掌握对二叉树的一些其它操作的具体实现方法。
2.掌握构造哈夫曼树以及哈夫曼编码的方法。
3、熟练掌握哈夫曼树(最优二叉树)特征及其应用
二、实验内容
题目一、哈夫曼树和哈夫曼编码:
从终端输入若干个字符,统计(或指定)字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树,然后对各字符进行哈夫曼编码。
最后打印哈夫曼树和对应的哈夫曼编码。
三、实验步骤
㈠、数据结构与核心算法的设计描述
typedefstruct
{
unsignedintweight;
unsignedintparent,lchild,rchild;
}HTNode,*HuffmanTree;
//定义哈夫曼树的结点类型
typedefchar**HuffmanCode;//哈夫曼编码的指针类型声明
typedefstructnode
{
chara;
intlog;
}node;
//定义输入的字符串的存储结点类型
int*w,num;//w为存储各种字符的权值的指针,num为字符串中出现的各种字符的类型个数
char*chartype;//定义存储各种字符的指针
HuffmanTreeHT;//定义存储哈夫曼树的指针
HuffmanCodecode;//定义存储各种字符的哈夫曼编码的指针
nodetest[1000];//定义存储输入字符串的数组
相关函数声明:
voidSaveTest(node*test)
//将输入的字符串存入test数组中,并将结点中的标志log记为0
intTestSum(node*test)
//统计数组test中字符的个数
intfreqchar(node*test,int*&w)
//统计数组test中各种字符出现的频率,并将不同种类的字符存入chartype数组中,将各种字符各自出现的次数存入数组w中
voidSelect(HuffmanTree&HT,intx,int&s1,int&s2)
//从哈夫曼树(以静态链表存储)前x个结点中选取权值最小的两个结点,并将其所处位置分别赋给s1和s2
intcreatehtree(HuffmanTree&HT,int*w)
//根据哈夫曼树构造规则,利用数组w中的权值构造哈夫曼树
voidcoding(HuffmanTree&HT,HuffmanCode&code)
//从叶子到根逆向求每个字符的哈夫曼编码
voidPrintCode(HuffmanCode&code)
//输出不同字符的哈夫曼编码
intLocate(chara,char*&b)
//查找字符a在数组b中的位置
voidPrintStrCode(node*test,HuffmanCode&code)
//输出test数组中存储的输入字符串所对应的哈夫曼编码
voidprinthtree(HuffmanTree&HT,inti)
//按中序遍历次序输出哈夫曼树中的所有结点
㈡、函数调用及主函数设计
㈢程序调试及运行结果分析
在调试过程中,Select(HuffmanTree&HT,intx,int&s1,int&s2)
函数所得结果不是正确结果,导致在建立哈夫曼树时没有得到想要的结果,经过修正Select函数,最终正确运行;还有一个就是中序输出哈夫曼树中的所有结点值这个函数,我参考于二叉树的中序遍历,但是二叉树中是链式存储的,经过一番考虑,将其转化为实现中序遍历哈夫曼树的算法。
㈣实验总结
这次的实验使得我对哈夫曼编码的实现及哈夫曼树的构造规则有了更深入的了解,运用起来更加地熟练,了解了哈夫曼树的存储结构,及实现哈夫曼编码的算法,能根据具体情况得到相应的哈夫曼树,进而的到哈夫曼编码,了解了合理地利用适当的存储结构可以简化算法,同时更好的节省空间、时间。
四、主要算法流程图及程序清单
1、主要算法流程图:
(部分)
将输入的字符串存入test数组中,并将结点中的标志log记为0voidSaveTest(node*test)
是
否
统计数组test中各种字符出现的频率,并将不同种类的字符存入chartype数组中,将各种字符各自出现的次数存入数组w中
intfreqchar(node*test,int*&w)
从哈夫曼树(以静态链表存储)前x个结点中选取权值最小的两个结点,并将其所处位置分别赋给s1和s2
voidSelect(HuffmanTree&HT,intx,int&s1,int&s2)
根据哈夫曼树构造规则,利用数组w中的权值构造哈夫曼树
intcreatehtree(HuffmanTree&HT,int*w)
是
否
否
是
否
是
否
是
从叶子到根逆向求每个字符的哈夫曼编码voidcoding(HuffmanTree&HT,HuffmanCode&code)
否
是
否
是
2、程序清单
#include
#include
#include
//包含头文件
typedefstruct
{
unsignedintweight;
unsignedintparent,lchild,rchild;
}HTNode,*HuffmanTree;
//定义哈夫曼树的结点类型
typedefchar**HuffmanCode;//哈夫曼编码的指针类型声明
typedefstructnode
{
chara;
intlog;
}node;
//定义输入的字符串的存储结点类型
int*w,num;//w为存储各种字符的权值的指针,num为字符串中出现的各种字符的类型个数
char*chartype;//定义存储各种字符的指针
HuffmanTreeHT;//定义存储哈夫曼树的指针
HuffmanCodecode;//定义存储各种字符的哈夫曼编码的指针
nodetest[1000];//定义存储输入字符串的数组
voidSaveTest(node*test)
//将输入的字符串存入test数组中,并将结点中的标志log记为0
{
chara='\0';
inti=0;
cout< while(a! ='@') { cin>>a; test[i].a=a; test[i].log=0; i++; } } intTestSum(node*test) //统计数组test中字符的个数 { inti=0; while(test[i].a! ='@') i++; returni; } intfreqchar(node*test,int*&w) //统计数组test中各种字符出现的频率,并将不同种类的字符存入chartype数组中,将各种字符各自出现的次数存入数组w中 { inti=0,j=1,sum=0,k; while(test[i].a! ='@') { if(test[i].log! =-1) { sum++; j=i+1; while(test[j].a! ='@') { if(test[j].a==test[i].a) test[j].log=-1; j++; } } i++; } num=sum; w=newint[sum]; chartype=newchar[sum]; i=0,j=1,sum=1,k=0; while(test[i].a! ='@') { sum=1; if(test[i].log! =-1) { chartype[k]=test[i].a; j=i+1; while(test[j].a! ='@') { if(test[j].a==test[i].a) sum++; j++; } w[k]=sum; k++; } i++; } return1; } voidSelect(HuffmanTree&HT,intx,int&s1,int&s2) //从哈夫曼树(以静态链表存储)前x个结点中选取权值最小的两个结点,并将其所处位置分别赋给s1和s2 { HuffmanTreep; inti,k; unsignedinta; p=HT+1; i=0; while(p->parent! =0&&i+1<=x) { p++;i++; } p=p+i; k=i+1; a=p->weight; for(p=HT+1,i=1;i<=x;++i,++p) { if(p->weightparent==0) { a=p->weight;k=i; } } s1=k; HT[s1].parent=-1; p=HT+1; i=0; while(p->parent! =0&&i+1<=x) { p++;i++; } p=p+i; k=i+1; a=p->weight; for(p=HT+1,i=1;i<=x;++i,++p) { if(p->weightparent==0) { a=p->weight;k=i; } } s2=k; HT[s2].parent=-1; } intcreatehtree(HuffmanTree&HT,int*w) //根据哈夫曼树构造规则,利用数组w中的权值构造哈夫曼树 { HuffmanTreep; intm,i,s1,s2; if(num<=1)return0; m=2*num-1; HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); for(p=HT+1,i=1;i<=num;++i,++p,++w) { p->weight=*w;p->parent=0; p->lchild=0;p->rchild=0; } for(;i<=m;++i,++p) { p->weight=0;p->parent=0; p->lchild=0;p->rchild=0; } for(i=num+1;i<=m;++i) { 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; } return1; } voidcoding(HuffmanTree&HT,HuffmanCode&code) //从叶子到根逆向求每个字符的哈夫曼编码 { char*cd; intstart,f; unsignedintc; code=(HuffmanCode)malloc((num+1)*sizeof(char*)); cd=(char*)malloc(num*sizeof(char)); cd[num-1]='\0'; for(inti=1;i<=num;i++) { start=num-1; for(c=i,f=HT[i].parent;f! =0;c=f,f=HT[f].parent) if(HT[f].lchild==c) cd[--start]='0'; else cd[--start]='1'; code[i]=(char*)malloc((num-start)*sizeof(char)); strcpy(code[i],&cd[start]); } free(cd); } voidPrintCode(HuffmanCode&code) //输出不同字符的哈夫曼编码 { for(inti=1;i<=num;i++) cout< "< } intLocate(chara,char*&b) //查找字符a在数组b中的位置 { inti=0; while(b[i]! =a) i++; returni; } voidPrintStrCode(node*test,HuffmanCode&code) //输出test数组中存储的输入字符串所对应的哈夫曼编码 { inti=0; while(test[i].a! ='@') { cout< i++; } cout< } voidprinthtree(HuffmanTree&HT,inti) //按中序遍历次序输出哈夫曼树中的所有结点 { if(i==0)return; else { printhtree(HT,HT[i].lchild); cout< if(i>=1&&i<=num) cout<<"("< else cout<<""; printhtree(HT,HT[i].rchild); } } voidmain() { inti; SaveTest(test); freqchar(test,w); cout< cout<<"各种字符出现的频率为: "< for(i=0;i<=num-1;i++) cout< "<<(double)((double)w[i]/(double)TestSum(test))< if(createhtree(HT,w)) { cout< "< printhtree(HT,2*num-1); cout< coding(HT,code); cout<<"各种字符对应的哈夫曼编码为: "< PrintCode(code); cout< "< PrintStrCode(test,code); cout< deletew; deletechartype; for(i=1;i<=num;i++) deletecode[i]; deletecode; deleteHT; } else { cout< "< cout< cout<<"各种字符对应的哈夫曼编码为: "< cout< "<<"1"< cout< "< cout<<"1"< deletechartype; } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验 报告