一定要亲自试了,才会印象深刻呢!!!
//HuffmanTree
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define UNIT_MAX 10000
typedef struct
{
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree; //动态分配数组存储HuffmanTree
typedef char **HuffmanCode;//动态分配数组存储HuffmanCode
int min1(HuffmanTree t,int i)
{//函数VOID select调用
int j,flag;
unsigned int k=UNIT_MAX;//取K为最小可能的值
for(j=1;j<=i;j++)
if(t[j].weight<k && t[j].parent==0)
{
k=t[j].weight;
flag=j;
}
t[flag].parent=1;
return flag;
}
void select(HuffmanTree HT,int i,int *s1,int *s2)
{
int j;
*s1=min1(HT,i);
*s2=min1(HT,i);
if(*s1>*s2)
{
j=*s1;
*s1=*s2;
*s2=j;
}
}
void HuffmanCoding(HuffmanTree *HT,HuffmanCode *HC,int *w,int n) //这里也是必须用两个*,我开始以为不用的呢。。。
{//w存放n个字符的权值(>0),构造哈弗曼树HT,并求出n个字符的哈弗曼编码HC、
int m,i;
HuffmanTree p;
if(n<=1) return ;
m=2*n-1;
*HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); //0号单元未用
for(p=*HT+1,i=1;i<=n;++i,++p,++w)
{
p->weight=*w;
p->parent=0;
p->lchild=0;
p->rchild=0;
}
for(;i<=m;++i,++p)
{
p->weight=0;
p->parent=0;
p->lchild=0;
p->rchild=0;
}
for(i=n+1;i<=m;++i)//建HuffmanTree
{//在HT[1..i-1]中选择parent为0且weight最小的两个节点,其序号分别为s1,s2.
int s1,s2;
select(*HT,i-1,&s1,&s2); //选出最小的两个节点
(*HT)[s1].parent=i;(*HT)[s2].parent=i;
(*HT)[i].lchild=s1;(*HT)[i].rchild=s2;
(*HT)[i].weight=(*HT)[s1].weight+(*HT)[s2].weight;
}
//-------------从叶子到根逆向求每个字符的HuffmanCode--------
*HC=(HuffmanCode)malloc((n+1)*sizeof(char*)); //分配n个字符编码的头指针向量
char *cd;
cd=(char*)malloc(n*sizeof(char));
cd[n-1]='\0';
//分配求编码的工作空间
for(i=1;i<=n;++i)
{
int start=n-1;
int f,c;
for(c=i,f=(*HT)[i].parent;f!=0;c=f,f=(*HT)[f].parent) //从叶子到根逆向求编码 从第一个节点开始遍历
if((*HT)[f].lchild==c)
cd[--start]='0';
else
cd[--start]='1';
(*HC)[i]=(char*)malloc((n-start)*sizeof(char)); //为第i个字符编码分配空间
strcpy((*HC)[i],&cd[start]); //从cd复制编码串到HC 这个超经典啊 为什么要用个&!!
}
free(cd);
}//HuffmaCoding
int main()
{
HuffmanTree HT;
HuffmanCode HC;
int *w,n,i;
printf("请输入权值的个数(>1):");
scanf("%d",&n);
w=(int*)malloc(n*sizeof(int));//为数据开辟空间
printf("请依次输入%d个权值(整型):\n",n);
for(i=0;i<=n-1;i++)
scanf("%d",w+i);
HuffmanCoding(&HT,&HC,w,n);
for(i=1;i<=n;i++)
puts(HC[i]);
return 0;
}