#include
#include
#include
#define N 20
#define M 2*N-1
typedef struct
//哈夫曼树的类型定义
{
int weight;
int parent;
int LChild;
int RChild;
}HTNode,HuffmanTree[M+1];
typedef char *HuffmanCode[N+1];
void CrtHuffmanTree(HuffmanTree ht,int w[],int n)
//构造哈夫曼树ht[M+1],w[]存放n个权值
{
int i,k,Lnode,Rnode,Min1,Min2,max=0;
int m=2*n-1;
for(i=1;i<=n;i++) //叶子结点初始化
{
ht[i].weight=w[i];
ht[i].parent=0;
ht[i].LChild=0;
ht[i].RChild=0;
}
for(i=n+1;i<=m;i++) //非叶子结点初始化
{
ht[i].weight=0;
ht[i].parent=0;
ht[i].LChild=0;
ht[i].RChild=0;
}
for(i=n+1;i<=m;i++)//建立哈夫曼树
{
Min1=Min2=10000;
Lnode=Rnode=0;//Lnode存放最小值的位置,Rnode存放第二最小值的位置
for(k=1;k
{
if(ht[k].parent==0)
{
if(ht[k].weight
{
Min2=Min1;
Rnode=Lnode;
Min1=ht[k].weight;
Lnode=k;
}
else
if(k!=Lnode&&ht[k].weight
{
Min2=ht[k].weight;
Rnode=k;
}
}
}
ht[i].weight=Min1+Min2;
ht[i].LChild=Lnode;ht[i].RChild=Rnode;
ht[Lnode].parent=i;ht[Rnode].parent=i;
}
printf("\n哈夫曼树的终态\n序号\tWeight\tParent\tLChild\tRChild\n");
for(i=1;i<=m;i++)//测试代码
{
printf("%d",i);
printf(" %d",ht[i].weight);
printf(" %d",ht[i].parent);
printf(" %d",ht[i].LChild);
printf(" %d",ht[i].RChild);
printf("\n");
}
printf("\n");
}
void CrtHuffmanCode(HuffmanTree ht,int n)
//从叶子结点到根,逆求每个叶子结点对应的哈夫曼编码,左0右1
{
char *cd;
int i,j,c,p,start;
cd=(char *)malloc(n*sizeof(char));
//分配求当前编码的工作空间
cd[n-1]='\0';//从右向左逐位存放编码,首先存放编码结束符
for(i=1;i<=n;i++)//求n个叶子结点对应的哈夫曼编码
{
start=n-1;//初始化编码起始指针
c=i;p=ht[i].parent;
//从叶子结点开始向上倒推,寻找该叶子结点的父母
while(p!=0)
{
--start;
if(ht[p].LChild==c)
cd[start]='0';//判断是左边还是右边,左分支标0
else
cd[start]='1';//右分支标1
c=p;p=ht[p].parent;//继续向上倒推
}
//hc[i]=(char *)malloc((n-start)*sizeof(char));
//strcpy(hc[i],&cd[start]);
for(j=0;j
{
if(cd[j]=='0'||cd[j]=='1')
printf("%c",cd[j]);
}
printf("\t");
for(j=0;j
{
cd[j]=' ';
}
}
free(cd);
}
void main()
{
HuffmanTree ht1;
// HuffmanCode hc;
char ch[20];
int i,a,w[20];
printf("请输入字符个数(小于20):");
scanf("%d",&a);
printf("请输入字符:");
getchar();
for(i=1;i<=a;i++)//输入字符
ch[i]=getchar();
getchar();
printf("请输入各个字符对应的权值:");
for(i=1;i<=a;i++)//输入各个字符对应的权值
scanf("%d",&w[i]);
CrtHuffmanTree(ht1,w,a);//调用函数构造哈夫曼树
printf("\n\t\t各字符的哈夫曼树编码\n");
printf("\t字符\t");
for(i=1;i<=a;i++)
printf("%c\t",ch[i]);
printf("\n\t权值\t");
for(i=1;i<=a;i++)
printf("%d\t",w[i]);
printf("\n 哈夫曼编码\t");
CrtHuffmanCode(ht1,a);//调用函数输出哈夫曼编码
printf("\n");
}