实验名称:树和二叉树的基本运算实现
指导教师: 王莹洁
专业班级: 计163-1
姓 名: 曹欣宇
学 号: 201658503125
一、实验题目
设计一个程序exp7-6.cpp,构造一棵哈夫曼树,输出对应的哈夫曼编码和平均查找长度。并用表7.8所示的数据进行验证。
单词 | The | of | a | to | and | in | that | he | is | at | on | for | His | are | be |
出现频度 | 1192 | 677 | 541 | 518 | 462 | 450 | 242 | 195 | 190 | 181 | 174 | 157 | 138 | 124 | 123 |
表7.8 单词及出现的频度
掌握哈夫曼树的构造过程和哈夫曼编码的产生方法;灵活运用二叉树这种数据结构解决一些综合应用问题。
针对程序exp7-6.cpp,输出结果如下:
见运行图。
四、实验步骤
(包括基本设计思路、算法设计、函数相关说明、输入与输出以及程序运行结果)
基本设计思路:函数分块程序设计。
算法设计:设置一个结构体typedefstruct{char s[20];double pweight} Node;用来存储题目信息。主函数中,先将频度转换为频率,然后分别给树的data域以及weight域赋值。先进入最小二叉树函数,从权值中选取两个最小的构成子树,最后得到最小二叉树。再进入编码函数,给所有的左分支加上0,右分支加上1,即可得到哈夫曼编码,最后输出。
函数相关说明:void createHT(HTNode ht[],intn)//生成最小二叉树函数
void createHCode(HTNodeht[],HCode hcd[],int n)//生成哈夫曼编码函数
输入:无。
输出:见运行图。
运行结果:
五、实验心得体会
通过实验,掌握了哈夫曼树以及哈夫曼编码的实现。
六、源程序清单(代码)
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
typedef struct
{
char s[20];
double pweight;
} Node;
typedef struct
{
char data[20];
double weight;
int parent;
int lchild;
int rchild;
} HTNode;
typedef struct
{
char cd[50];
int start;
} HCode;
HTNode ht[20];//注:该程序中,此定义必须为全局变量,否则不可运行,原因不详.....
void createHT(HTNode ht[],int n)
{
int i,k,lnode,rnode;
double min1,min2;
for (i=0; i<2*n-1; i++)
ht[i].parent=ht[i].lchild=ht[i].rchild=-1;
for (i=n; i<2*n-1; i++)
{
min1=min2=32767;
lnode=rnode=-1;
for (k=0; k<=i-1; k++)
if (ht[k].parent==-1)
{
if (ht[k].weight<min1)
{
min2=min1;
rnode=lnode;
min1=ht[k].weight;
lnode=k;
}
else if (ht[k].weight<min2)
{
min2=ht[k].weight;
rnode=k;
}
}
ht[i].weight=ht[lnode].weight+ht[rnode].weight;
ht[i].lchild=lnode;
ht[i].rchild=rnode;
ht[lnode].parent=i;
ht[rnode].parent=i;
}
}
void createHCode(HTNode ht[],HCode hcd[],int n)
{
int i,f=0,c;
HCode hc;
for (i=0; i<n; i++)
{
hc.start=n;
c=i;
f=ht[i].parent;
while (f!=-1)
{
if (ht[f].lchild==c)
hc.cd[hc.start--]='0';
else
hc.cd[hc.start--]='1';
c=f;
f=ht[f].parent;
}
hc.start++;
hcd[i]=hc;
}
}
int main()
{
int i,k,j,m;
double sum=0,n1=0;
Node node[20]= {{"The",1192},{"of",677},{"a",541},{"to",518},{"and",462},{"in",450},{"that",242},{"he",195},{"is",190},{"at",181},{"on",174},{"for",157},{"His",138},{"are",124},{"be",123}};
HCode hcd[20];
double weight[20];
for(i=0; i<15; i++)
{
weight[i]=node[i].pweight/5364;
}
for(i=0; i<15; i++)
{
ht[i].weight=weight[i];
strcpy(ht[i].data,node[i].s);
}
createHT(ht,15);
createHCode(ht,hcd,15);
printf("输出哈夫曼编码:\n");
for (m=0; m<15; m++)
{
j=0;
printf("\t%s\t",ht[m].data);
for (k=hcd[m].start; k<=15; k++)
{
printf("%c",hcd[m].cd[k]);
j++;
}
n1+=ht[m].weight;
sum+=ht[m].weight*j;
printf("\n");
}
printf("平均长度=%f\n",sum/n1);
return 0;
}