二叉树的应用实验报告材料.docx
- 文档编号:23814642
- 上传时间:2023-05-21
- 格式:DOCX
- 页数:10
- 大小:17.44KB
二叉树的应用实验报告材料.docx
《二叉树的应用实验报告材料.docx》由会员分享,可在线阅读,更多相关《二叉树的应用实验报告材料.docx(10页珍藏版)》请在冰豆网上搜索。
二叉树的应用实验报告材料
实验报告
课程名称____数据结构上机实验__________
实验项目______二叉树的应用____________
实验仪器________PC机___________________
系别____________________________
专业_____________________________
班级/学号____________________________
学生姓名_____________________________
实验日期_______________________
成绩_______________________
指导教师_______________________
实验三.二叉树的应用
1.实验目的:
掌握二叉树的链式存储结构和常用算法。
利用哈夫曼树设计最优压缩编码。
2.实验内容:
1)编写函数,实现建立哈夫曼树和显示哈夫曼树的功能。
2)编写函数,实现生成哈夫曼编码的功能。
3)编写主函数,从终端输入一段英文文本;统计各个字符出现的频率,然后构建哈夫曼树并求出对应的哈夫曼编码;显示哈夫曼树和哈夫曼编码。
选做内容:
修改程序,选择实现以下功能:
4)编码:
用哈夫曼编码对一段英文文本进行压缩编码,显示编码后的文本编码序列;
5)统计:
计算并显示文本的压缩比例;
6)解码:
将采用哈夫曼编码压缩的文本还原为英文文本。
3.算法说明:
1)二叉树和哈夫曼树的相关算法见讲义。
2)编码的方法是:
从头开始逐个读取文本字符串中的每个字符,查编码表得到它的编码并输出。
重复处理直至文本结束。
3)解码的方法是:
将指针指向哈夫曼树的树根,从头开始逐个读取编码序列中的每位,若该位为1则向右子树走,为0则向左子树走。
当走到叶子节点时,取出节点中的字符并输出。
重新将指针放到树根,继续以上过程直至编码序列处理完毕。
4)压缩比例的计算:
编码后的文本长度为编码序列中的0和1,的个数,原文本长度为字符数*8。
两者之比即为压缩比。
4.实验步骤:
实现哈夫曼树的编码序列操作:
inti=0,j=0;
huffnodep;
p=tree[2*n-2];//序号2*n-2节点就是树根节点
while(hfmstr[i]!
='\0')//从头开始扫描每个字符,直到结束
{while(p.lchild!
=-1&&p.rchild!
=-1)
if(hfmstr[i]=='0')//为0则向左子树走
{
p=tree[p.lchild];//取出叶子节点中的字符
}
elseif(hfmstr[i]=='1')//为1则向右子树走
{
p=tree[p.rchild];//取出叶子节点中的字符
}
i++;
}
decodestr[j]=p.data;j++;//对字符进行译码,结果放在decodestr字符串中
p=tree[2*n-2];//返回根节点
}
}
程序修改后完整源代码如下:
#include
#include
#include
#include
#defineN96//ASCII字符集包含至多N个可见字符
typedefstruct//Huffman树节点定义
{chardata;//字符值
intweight;//权重
intlchild;//左子结点
intrchild;//右子结点
}huffnode;//huffman节点类型
structcharcode
{intcount;//字符出现的次数(频率)
charcode[N];//字符的Huffman编码
}codeset[N];//编码表,长为N,每项对应一个ascii码字符,下标i的项对应ascii编码为i+32的字符
huffnode*CreateHufftree(chardata[],intweight[],intn)//建立Huffman树的算法
{
inti,k;
intmin1,min2,min_i1,min_i2;
huffnode*tree;
tree=(huffnode*)malloc((2*n-1)*sizeof(huffnode));//为Huffman树分配2n-1个节点空间
for(i=0;i<2*n-1;i++)//初始化,将各字符和其频率填入Huffman树,作为叶子结点
{
tree[i].lchild=tree[i].rchild=-1;
if(i tree[i].data=data[i]; tree[i].weight=weight[i]; } elsetree[i].data=''; } for(i=n;i<2*n-1;i++)////合并两棵树,作n-1遍 { min1=min2=INT_MAX;//INT_MAX为最大值 min_i1=min_i2=-1; for(k=0;k if(tree[k].weight>=0)//仅在根节点中找 if(tree[k].weight { min2=min1; min_i2=min_i1; min1=tree[k].weight; min_i1=k; } else if(tree[k].weight min2=tree[k].weight; min_i2=k; } tree[i].weight=min1+min2;//合并 tree[min_i1].weight*=-1; tree[min_i2].weight*=-1; tree[i].lchild=min_i1; tree[i].rchild=min_i2; } returntree; } voidCreateHuffcode(huffnodetree[],inti,chars[])//已知tree[i]节点的编码序列为s,求该节点下所有叶子节点的编码序列。 {chars1[N],c; if(i! =-1) if(tree[i].lchild==-1&&tree[i].rchild==-1){ c=tree[i].data; strcpy(codeset[c-32].code,s); } else{ strcpy(s1,s);strcat(s1,"0"); CreateHuffcode(tree,tree[i].lchild,s1); strcpy(s1,s);strcat(s1,"1"); CreateHuffcode(tree,tree[i].rchild,s1); } return; } voidPrintHufftree(huffnodetree[],intn)//输出tree中的Huffman树 { inti; printf("Huffmantree: \n"); printf("i\tValue\tLchild\tRchild\tWeight\n"); for(i=2*n-2;i>=0;i--) { printf("%d\t",i); printf("%c\t",tree[i].data); printf("%d\t",tree[i].lchild); printf("%d\t",tree[i].rchild); printf("%d\t",tree[i].weight); printf("\n"); } } voidEnCoding(charstr[],charhfmstr[]) {//根据codeset编码表,逐个将str字符串中的字符转化为它的huffman编码,结果编码串放在hfmstr字符串中 inti,j; hfmstr[0]='\0';//把hfmstr串赋空 i=0; while(str[i]! ='\0')//从第头开始扫描str的每个字符,一直到该字符的结束 { j=str[i]-32;//执行字符到huffman的转换 strcat(hfmstr,codeset[j].code);//把codest编码串添加到hfmstr结尾处 i++;//每次循环完i的值加1 } } voidDeCoding(huffnodetree[],intn,charhfmstr[],chardecodestr[]) //根据tree数组中的huffman树,逐个对hfmstr字符串中的字符进行译码,结果放在decodestr字符串中 { inti=0,j=0; huffnodep; p=tree[2*n-2];//序号2*n-2节点就是树根节点 while(hfmstr[i]! ='\0')//从头开始扫描每个字符,直到结束 {while(p.lchild! =-1&&p.rchild! =-1)//指针为空,儿子的值取完了 { if(hfmstr[i]=='0')//为0则向左子树走 { p=tree[p.lchild];//取出叶子节点中的字符 } elseif(hfmstr[i]=='1')//为1则向右子树走 { p=tree[p.rchild];//取出叶子节点中的字符 } i++; } decodestr[j]=p.data;j++;//对字符进行译码,结果放在decodestr字符串中 p=tree[2*n-2];//返回根节点 } } voidmain() { inti,j; huffnode*ht;//Huffman树 chardata[N];//要编码的字符集合 intweight[N];//字符集合中各字符的权重(频率) intn=0;//字符集合中字符的个数 charstr[1000];//需输入的原始字符串 charhfm_str[1000]="";//编码后的字符串 chardecode_str[1000]="";//解码后的字符串 printf("请输入要转换的字符串\n"); gets(str); for(i=0;i codeset[i].count=0; codeset[i].code[0]='\0'; } i=0; while(str[i]! ='\0'){//统计原始字符串中各字符出现的频率,存入编码表 j=str[i]-32; codeset[j].count++;//codeset[0]~[95]对应ascii码32~127的字符 i++; } for(i=0;i if(codeset[i].count! =0)n++; printf("字符频率统计: \n");//显示统计结果 for(i=0;i if(codeset[i].count! =0)printf("%c: %d,",i+32,codeset[i].count); printf("\n"); j=0; for(i=0;i if(codeset[i].count! =0){ data[j]=i+32; weight[j]=codeset[i].count; j++; } ht=CreateHufftree(data,weight,n);//建立Huffman树,根节点是ht[2*n-2] PrintHufftree(ht,n);//显示Huffman树的存储结果 CreateHuffcode(ht,2*n-2,"");//以ht[2*n-2]为根,以空字符串为起始编码字符串,求出各叶子节点的编码字符串 //显示codeset中的Huffman编码,参见"显示频率统计结果"的代码. printf("haffman编码为: \n"); for(i=0;i if(codeset[i].count! =0) printf("%c: %s\n",i+32,codeset[i].code); } EnCoding(str,hfm_str);//对str字符串进行编码,放在hfm_str字符串 printf("编码序列: %s\n",hfm_str); DeCoding(ht,n,hfm_str,decode_str);//对hfm_str字符串进行译码,放在decode_str字符串中 printf("解码后的字符串: %s\n",decode_str); free(ht);//释放Huffman树 } 实验总结:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 二叉 应用 实验 报告 材料