哈夫曼树实验报告
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
typedef struct{ char ch;
//字母的种类
int num; }inf;
//字母的个数
一2一 在构造哈夫曼树时,设计一个结构体数组Hufftree保存哈夫曼树中各结
点的信息,根据二叉树的性质可知,具有n个结点的哈夫曼树共有2n-1个结
点,所以数组大小设置为2n-1,描述结点的数据类型为:
一4一 建立哈夫曼编码的功能模块 此模块功能为将(2)中建立的哈夫曼树进行哈弗曼编码,然后将字符 与对应的0、1代码串打印到屏幕上。
函数原型:void huffmancode(Hnodetype *hufftree) 如输入的字符串是“sddfffgggg”,则每个字母的代码和输入的字符串 的哈夫曼编码是
for(j=cd.start+1;j<n;j++)
//将结果保存
huffcode[i].bit[j]=cd.bit[j];//保存每位号码
huffcode[i].start=cd.start; } cout<<endl<<endl<<endl;
cout<<"哈弗曼编码"<<endl;
//保存开始位置
2、构造哈夫曼树 统计出的字母种类为叶子结点个数,每个字母个数为相应的权值,建立哈 夫曼树。
3、打印哈弗曼树的功能模块 按照一定形式打印出哈夫曼树。
4、编码 利用已经建立好的哈夫曼树进行编码。
5、译码 根据编码规则对输入的代码进行翻译并将译码。
1、实验问题分析
三、实验步骤
一1一 设计一个结构体数组保存字母的类型和个数。
数学与计算机学院 数据结构 实验报告
年级 09数计 学号 2009432125 姓名 刘宝 成绩 专业 数电 实验地点 主楼401 指导教师 苗秀芬 实验项目 哈夫曼树解决编码解码 实验日期 10年12月24日
一、实验目的
本实验的目的是通过对简单的哈夫曼编/译码系统的设计与实现来熟练掌握 树形结构在实际问题中的应用。
四、实验结果(程序)及分析
1、实验主要模块代码
(一) 函数功能:统计字母种类和个数模块
void fundchar() {
int k,m; cout<<"请输入字符串"<<endl;
cin>>s;
//s为输入的字符串
while(s[v]){v++;} cout<<"共有字符"<<v<<"个"<<endl;
//求每个结点的哈弗曼编码
cd.start=n-1; c=i; p=hufftree[c].parent;
while(p!=-1){
//由叶子结点向上直到树根
if(hufftree[p].lchild==c) cd.bit[cd.start]=0;
else cd.bit[cd.start]=1;
cd.start--; c=p; p=hufftree[c].parent; }
int i,j,m1,m2,x1,x2;
//m1记录最小的重权值,m2为次小
for(i=0;i<2*n-1;i++){
hufftree[i].parent=-1; hufftree[i].weight=0; hufftree[i].lchild=-1; hufftree[i].rchild=-1;
//结点初始化
num++;
//确定0,1代码长度
Hnodetype *p=&hufftree[2*n-2]; cout<<endl<<endl<<endl;
cout<<"译码结果----"<<endl;
for(int i=0;i<num;i++){ if(code[i]=='0')
p=&hufftree[p->lchild]; else
//x1记录最小重权值在数组中的下标
} else if(hufftree[j].parent==-1 && hufftree[j].weight<m2){
m2=hufftree[j].weight; x2=j;
//x2记录次小重权值在数组中的下标
} } hufftree[x1].parent=n+i; hufftree[x2].parent=n+i; hufftree[n+i].weight=m1+m2; hufftree[n+i].lchild=x1; hufftree[n+i].rchild=x2; }
int bit[maxbit];
//每个结点的哈夫曼编码
int start; }Hcodetype;
//开始位置
一4一 设置全局变量。
string s; //s为输入的字符串
int n=0;
//记录输入的字符串中字母的种类,即叶子结点个数
int v=0; //记录字符串中字母的总个数
inf info[maxleaf];//叶子结点类型
一5一 译码的功能模块 此模块的功能为接收需要译码的0和1代码串,按照(4)中建立的编码 规则将其翻译成字符集中字符所组成的字符串形式,并将翻译的结 果在屏幕上打印出来。
函数原型:void translation(Hnodetype *hufftree) 如输入的代码串是“110111100”,则对应的字符串是“sdfg”
typedef struct{ int weight;
//权值
int parent;
int lchild; int rchild;
//双亲
//左孩子 //右孩子
}Hnodetype; typedef Hnodetype Hufftree[maxnode];
//定义此类型的数组
、3、 求哈夫曼编码,实质上是在已经建立的哈夫曼树中,从叶子结点开始,
typedef struct{ char ch; int num; }inf;
cout<<endl<<"输入的字符串的哈夫曼编码为:"<<endl;
for(i=0;i<v;i++)//打印输入的字符串的编码结果
for(int y=0;y<=n;y++) if(s[i]==info[y].ch) {for(j= huffcode[y].start+1;j<n;j++)
cout<<huffcode[y].bit[j];} cout<<endl; }
p=&hufftree百度文库p->rchild];
//从根向下
if(p->lchild==-1 && p->rchild==-1){ //如果到达叶子结点
t=p->weight;
for(int j=0;j<n;j++) if(hufftree[j].weight==t){
//保存叶子结点的权值
cout<<info[j].ch; //输出权值的对应的字母
}
for(m=0;m<n;m++)
//输出种类和个数
cout<<"字符"<<info[m].ch<<"有"<<info[m].num<<"个"<<endl; }
(一) 函数功能:哈弗曼树的建立模块
Hnodetype* huffmantree(){ Hnodetype *hufftree=new Hufftree;
二、实验问题描述
利用哈夫曼编码进行通信可以大大提高通信利用率,缩短信息传输时间, 降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码, 在接收端将传来的数据进行译码,此试验即设计这样的一个简单的编/译码系统 。系统应该具备如下的几个功能。
1、求出各个叶子节点的权重值 输入一个字符串,统计其中各个字母的个数和总的字母个数。
2、 功能(函数)设计
一1一 统计字母种类和个数模块
此模块的功能为从键盘接受一个字符串,统计字符串中字母种类即 结点个数,每种字母出现次数即各叶子结点的权值。全局变量s保存 输入的字符串,将种类和个数保存到info[maxleaf]中。 函数原型:void fundchar() 如输入的字符串是“sddfffgggg”则显示如下。
(一) 函数功能:译码的功能模块
void translation(Hnodetype *hufftree){
string code;
//code记录输入的0,1代码
int t; cout<<endl<<endl<<endl;
cout<<"请输入代码串:";
cin>>code; int num=0; while(code[num])
// v是全局变量
info[0].ch=s[0];info[0].num=1; for(k=1;k<=v;k++)
//统计s中字母种类和个数
{ for(m=0;m<=n;m++) {if(info[m].ch==s[k]){++info[m].num;break;}} if(m>n){info[++n].ch=s[k];info[n].num=1;}
"<<"weight"<<"
"<<"lchild" <<"
"<<"parent"<<endl;
//界面优化
for(int i=0;i<2*n-1;i++)
cout<<"
"<<hufftree[i].weight<<"
"
<<hufftree[i].lchild<<"
"<<hufftree[i].rchild
<<"
"<<hufftree[i].parent<<endl;
}
(一) 函数功能:建立哈弗曼编码的功能模块
void huffmancode(Hnodetype *hufftree){ Hcodetype huffcode[maxleaf],cd; int i,j,c,p;
for(i=0;i<n;i++){
沿着结点的双亲链表域退回到根节点,每退回一步,就走过了哈夫曼树的一
个分支,从而得到一位哈夫曼值,由于一个字符的哈夫曼编码是从根结点所
经过的路径上各分支所组成的0、1序列,因此先得到的分支代码为所求编码
的低位码,后得到的分支代码为所求编码的高位码,所以设计如下的数据类
型: const int maxbit=10; typedef struct{
一2一 哈夫曼树的建立模块 此模块的功能为从(1)中计算出的结点个数和各个叶子结点的权值 构造一棵哈弗曼树。 函数原型:Hnodetype* huffmantree()//函数返回结点类型的数组
一3一 打印哈弗曼树的功能模块 此模块的功能是将由(2)建立的哈弗曼树按照一定规则<weight,lch ild,rchild,parent>打印在屏幕上。 函数原型:void print(Hnodetype *hufftree) 如输入的字符串是”sddfffgggg”,则构造的哈夫曼树为
} for(i=0;i<n;i++)
//将每个字母的个数当做叶子 结点的权值
hufftree[i].weight=info[i].num; for(i=0;i<n-1;i++){
m1=m2=maxvalue; x1=x2=0; for(j=0;j<n+i;j++){
if(hufftree[j].parent==-1 && hufftree[j].weight<m1){ m2=m1; x2=x1; m1=hufftree[j].weight; x1=j;
break; } p=&hufftree[2*n-2]; } } cout<<endl; }
2、测试数据
sfddaaassss 实验结果截图
//重新从根节点开始
3、 调试过程中出现的问题以及解决策略
译码模块中,如果输入的代码串无对应的字母,则会出错。 解决办法:提示用户输入时注意
附最终代码:
#include<iostream> #include<string> #define maxvalue 12 #define maxleaf 12 #define maxnode 23 using namespace std; int n=0; int v=0; string s;
for(i=0;i<n;i++)
//打印各个字母对应的编码
{ cout<<"-----------"<<endl;
cout<<info[i].ch<<"的代码是";
for(j=huffcode[i].start+1;j<n;j++)
cout<<huffcode[i].bit[j]; cout<<endl; } cout<<"-----------"<<endl;
return hufftree;
//返回数组首地址
}
(一) 函数功能:打印哈弗曼树的功能模块
void print(Hnodetype *hufftree){ cout<<endl<<endl<<endl; //界面优化
cout<<"哈弗曼树----"<<endl;
cout<<" "<<"rchild"<<"