构造哈弗曼树:
假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:
(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);
(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;
(3)从森林中删除选取的两棵树,并将新树加入森林;
(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。
实现哈弗曼树,输出哈弗曼编码:
#include<stdio.h>
#include<string.h>
#include<conio.h>
#include<stdlib.h>
#define M 20;
typedef struct
{
int weight;
int father;
int lchild;
int rchild;
char value;
}Node;
void input( Node *nodes)
{
int i;
for(i=0;i<10;i++)
{
printf("请输入第%d个节点的权重\n",i+1);
scanf("%d",&nodes[i].weight);
nodes[i].father=-1;
}
}
void con(Node *nodes)//构造哈弗曼树
{
int n=10;
int i,j,tem;
int m1,m2,x1,x2;
for(i=0;i<n-1;i++)
{
m1=m2=10000;
x1=x2=0;
for(j=0;j<n+i;j++)
{
if(nodes[j].weight<m1&&nodes[j].father==-1)
{
m2=m1;
x2=x1;
m1=nodes[j].weight;
x1=j;
}
else if(nodes[j].weight<m2&&nodes[j].father==-1)
{
m2=nodes[j].weight;
x2=j;
}
}
nodes[x1].father=n+i;
nodes[x2].father=n+i;
nodes[n+i].weight=nodes[x1].weight+nodes[x2].weight;
nodes[n+i].lchild=x1;
nodes[n+i].rchild=x2;
nodes[n+i].father=-1;
}
}
char * output(Node *nodes,int i,int j)
{
int k,m;
char *h;
char s[10]="\0";
int lenth;
if(nodes[i].lchild==j)
{
s[0]='0';
}
else if(nodes[i].rchild==j)
{
s[0]='1';
}
if(nodes[i].father==-1)
{
return h=s;
}
else
{
char *c=output(nodes,nodes[i].father,i);
lenth=strlen(c);
for(k=1,m=0;m<lenth;m++,k++)
{
s[k]=c[m];
}
h=s;
return h ;
}
}
int main()
{
int lenth;
int i,j,k,m,f;
char s[10]="\0";
char c[20];
Node nodes[20];
input(nodes);
con(nodes);
for(i=0;i<10;i++)
{
char *c=strrev(output(nodes,nodes[i].father,i));
lenth=strlen(c);
for(k=0,m=0;m<lenth;m++,k++)
{
s[k]=c[m];
}
printf("权重:%d\t,哈弗曼编码:",nodes[i].weight);
for(f=0;f<lenth;f++)
{
printf("%c",s[f]);
}
printf("\n");
}
getch();
return 0;
}