真想不到这样的小程序竟然可以用在分数判级,电报编码等众多领域,现在真感觉到数据结构的威力了!!!
#include "stdio.h"
#define LEN sizeof(struct Huffman)
#define SIZE 4
struct Huffman
{
int weight; //编码的权值
int parent,lchild,rchild; //双亲,左孩子,右孩子位置
char data; //字符
};
main()
{
int i,S1,S2;
int w[SIZE]={1,2,3,4}; //各字符权值数组
char c[SIZE]={'a','b','c','d'}; //字符数组
struct Huffman *hd,*p; //定义哈夫曼树hd并分配空间
char **hc;
hc=(char **)malloc((SIZE+1)*sizeof(char *));
hd=(struct Huffman *)malloc(2*SIZE*LEN);
for(i=1,p=hd+1;i<=SIZE;p++,i++) //为树上节点分配权值并初始化
{
p->weight=w[i-1];
p->parent=0;
p->lchild=0;
p->rchild=0;
p->data=c[i-1];
}
for (;i<2*SIZE;p++,i++)
{
p->weight=0;
p->parent=0;
p->lchild=0;
p->data=0;
p->rchild=0;
}
for(i=SIZE+1;i<2*SIZE;i++) //建立哈夫曼树
{
int weight1,weight2;
Select(hd,i-1,&S1,&S2); //从I-1个节点中选出2个权值最小的节点
p=hd+S1;
p->parent=i;
weight1=p->weight;
p=hd+S2;
p->parent=i;
weight2=p->weight;
p=hd+i;
p->lchild=S1;
p->rchild=S2;
p->weight=weight1+weight2;
}
for(i=1;i<=SIZE;i++) //从叶子到根逆向求每个字符的哈夫曼编码
{
int start,j,f;
char *cd;
cd=(char *)malloc(SIZE*sizeof(char));
*(cd+SIZE-1)='/0';
start=SIZE-1;
p=hd+i;
for(j=i,f=p->parent;f!=0;j=f,f=p->parent)
{
p=hd+f;
if(p->lchild==j)
*(cd+(--start))='0';
else
*(cd+(--start))='1';
strcpy(hc+i,cd+start);
}
printf("hc[i]:%s/n",hc+i); //输出每个字符的哈夫曼编码
}
getch();
}
Select(struct Huffman *hd,int m,int *S1,int *S2)
{
int i;
struct Huffman *p;
p=hd+1;
*S1=*S2=100; //先让S1和S2的初值为很大的数
for(i=1;i<=m;i++,p++)
{
if(p->weight<*S1&&p->parent==0)
*S1=i;
}
p=hd+1;
for(i=1;i<=m;i++,p++)
{
if(i==*S1) continue;
if(p->weight<*S2&&p->parent==0)
*S2=i;
}
}