哈夫曼树的应用与实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/*哈夫曼树的应用和实现
(1)根据输入的字符和相应的权值建立哈夫曼树,并输出已建的相应内容作
为检查;
(2)用哈夫曼树实现前缀编码,并输出各字符的编码串;
(3)输入一组二进制报文,进行译码,并输出译文。*/
#include
#include
#include
#include
#define N 1000 //定义结点数最大值
#define M 2*N-1
#define maxval 10000.0 //定义float的最大值
typedef struct //定义哈夫曼树类型
{
char data;
float weight;
int lchild,rchild,parent;
}hufmtree;
hufmtree tree[M];
typedef struct //定义哈夫曼树编码类型
{
char bits[N];
int start;
char data;
}codetype;
codetype code[N];
void HUFFMAN(hufmtree t[]);
void HUFFMANCODE(codetype code[],hufmtree t[]);
void HUFFMANDECODE(codetype code[],hufmtree t[]);
void OUTTREE(hufmtree t[]);
static int n,m; //定义静态全局变量n储存需要的结点数
//m为构建哈夫曼树后的总结点数
//菜单的建立
void main()
{
int x,flag1=0;
printf("\t\t\t哈夫曼树的应用和实现\n");
while(1)
{
printf("——————————————————————————————————\n");
printf("菜单:1 建立哈夫曼树 2 哈夫曼树编码 3 输入电文译码0 退出使用\n");
printf("——————————————————————————————————\n");
printf("请选择操作:\n");
scanf("%d",&x);
switch(x)
{
case 1:
HUFFMAN(tree);
break;
case 2:
HUFFMANCODE(code,tree);
break;
case 3:
HUFFMANDECODE(code,tree);
break;
case 0:
flag1=1; //输入号为0时使flag1=1
break;
default:
printf("输入的选择有误!请重新输入!\n");
break;
}
if(flag1) break; //表明选择了退出操作故跳出循环
}
printf("Thank You!\n");
}
//哈夫曼树的构建
void HUFFMAN(hufmtree t[])
{
int i,j,p1,p2;
char ch;
float small1,small2,f;
printf("请输入叶子结点数:\n");
scanf("%d",&n);
m=2*n-1;
for(i=0;i { tree[i].parent=0; tree[i].lchild=0; tree[i].rchild=0; tree[i].data='0'; tree[i].weight=0.0; } for(i=0;i { getchar(); //getchar 吃掉回车 printf("请输入第%d个结点的字符和权重(空格隔开):\n",i); scanf("%c %f",&ch,&f); //输入结点字符和权重 tree[i].data=ch; tree[i].weight=f; } for(i=n;i { p1=0;p2=0; //预置最小次小权值的下标为0 small1=maxval; //预置最小次小权值为float型最大值 small2=maxval; for(j=i-1;j>=0;j--) //循环找出最小、次小权值和下标 if(tree[j].parent==0) if((tree[j].weight-small1)<0.0001) //float精度,当两者之差小于0.0001认为相等 { small2=small1; //小于当前最小权值,更新最小权值和次小权值以及位置 small1=tree[j].weight; p2=p1; p1=j; } else if((tree[j].weight-small2)<0.0001) //小于当前次小权值,更新次小权值和位置 { small2=tree[j].weight; p2=j; } tree[p1].parent=i; //修改最小、次小结点的双亲为新生成的结点 tree[p2].parent=i; tree[i].lchild=p1; //新结点的左右孩子指向最小次小值的结点