#include <stdio.h>
#define MAXBIT 10 //定义霍夫曼树编码的位数,最多10位
#define MAXVALUE 10000 //定义霍夫曼树权值,最大10000
#define MAXLEAF 30 //定义霍夫曼树子节点个数,最多30个
#define MAXNODE MAXLEAF*2-1 //定义霍夫曼树总节点个数,最多59个
typedef struct {
int bit[MAXBIT]; //bit[MAXBIT]表示编码为0或者1的数组
int start; //start表示每个Huffman编码在数组中的起始位置
}Hcodetype; //定义霍夫曼编码的结构huffcode.
typedef struct {
float weight; //定义霍夫曼树节点的权值
int parent; //定义霍夫曼树节点的父节点
int lchild; //定义霍夫曼树节点的左子节点
int rchild; //定义霍夫曼树节点的右子节点
}Hnodetype; //定义霍夫曼树的结点结构huffnode.
void huffmantree(Hnodetype huffnode[MAXNODE],int n)
{
int i,j,x1,x2;
float m1,m2;
for(i=0;i<2*n-1;i++) //霍夫曼树初始化
{
huffnode[i].weight=0;
huffnode[i].parent=-1;
huffnode[i].lchild=-1;
huffnode[i].rchild=-1;
}
for(i=0;i<n;i++) //提示输入霍夫曼树每个节点的权值
{
printf("please input %d character's weight/n",i);
scanf("%f",&huffnode[i].weight);
}
for(i=0;i<n-1;i++)
{
m1=m2=MAXVALUE;
x1=x2=0;
for(j=0;j<n+i;j++) //找出根结点权值最小的两棵树
{
if(huffnode[j].weight<m1&&huffnode[j].parent==-1)
{
m2=m1;
x2=x1;
m1=huffnode[j].weight;
x1=j;
}
else if(huffnode[j].weight<m2&&huffnode[j].parent==-1)
{
m2=huffnode[j].weight;
x2=j;
}
}
huffnode[x1].parent=n+i; //将找出的两棵树合并为一棵子树
huffnode[x2].parent=n+i;
huffnode[n+i].weight=huffnode[x1].weight+huffnode[x2].weight;
huffnode[n+i].lchild=x1;
huffnode[n+i].rchild=x2;
}
}
void main()
{
Hnodetype huffnode[MAXNODE]; //定义霍夫曼树
Hcodetype huffcode[MAXLEAF],cd; //定义霍夫曼编码
int i,j,c,p,n;
printf("please input n/n"); //霍夫曼树子节点的个数
scanf("%d",&n);
huffmantree(huffnode,n); //构造霍夫曼树
for(i=0;i<n;i++) //求各字符的霍夫曼编码
{
cd.start=n-1;
c=i;
p=huffnode[c].parent;
while(p!=-1)
{
if(huffnode[p].lchild==c)
cd.bit[cd.start]=0;
else
cd.bit[cd.start]=1;
cd.start--;
c=p;
p=huffnode[c].parent;
}
for(j=cd.start+1;j<n;j++)
huffcode[i].bit[j]=cd.bit[j];
huffcode[i].start=cd.start;
}
for(i=0;i<n;i++) //输出字符的霍夫曼编码
{
printf("%d character is:",i);
for(j=huffcode[i].start+1;j<n;j++)
printf("%d",huffcode[i].bit[j]);
printf("/n");
}
}