/*赫夫曼树编码*/
#include<stdio.h>
#include<malloc.h>
#define MAX 1000
typedef struct
{
unsigned int weight; /*存放权*/
unsigned int parent,lchild,rchild;/*指向双亲树,左子树,右子树*/
}htnode,*huffmantree;
typedef char * *huffmancode; /*存储已知树的权*/
typedef struct
{
int a[MAX];
int b,t;
}stack; /*定义一个栈存放和输出赫夫曼编码*/
stack sta;
huffmantree htree;
huffmancode hcode;
int weight[9]={8,5,29,7,8,14,23,3,11};/*用于给数传递初始值*/
int t1=1,t2=0;
/*构造栈的函数*/
void initstack(stack *s)
{
s->b=0;
s->t=0;
}
/*入栈的函数*/
void push(stack *s,int e)
{
s->a[s->t]=e;
++(s->t);
}
/*出栈的函数--一次输出所有栈内元素*/
void pop(stack *s)
{
int i;
for(i=0;i<s->t;++i)
{
printf("%d",s->a[i]);
}
printf("/n");
}
/*在从1-n的权值里寻找最小和次最小的树的序号,并用s1,s2返回的函数*/
void select(huffmantree *ht,int n,int *s1,int *s2)
{
unsigned int i,t,mid;
t=1000;
for(i=1;i<=n;++i)
{
if(t>(*ht)[i].weight&&(*ht)[i].parent==0)
{t=(*ht)[i].weight;
*s1=i;}
}
t=1000;
for(i=1;i<=n;++i)
{
if(i==*s1)continue;
if(t>(*ht)[i].weight&&(*ht)[i].parent==0)
{t=(*ht)[i].weight;
*s2=i;}
}
if(*s1>*s2)
{mid=*s1;*s1=*s2;*s2=mid;}
}
/*生成赫夫曼编码的函数*/
void createhu(huffmantree *ht,huffmancode *hc,int *w,int n)
{
int m,i,p,z;
int sa,sb;
void print(huffmantree *ht);
m=n*2-1;
*ht=(huffmantree)malloc((m+1)*sizeof(htnode));
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;
}
print(ht);
for(i=n+1;i<=m;++i)
{
select(ht,i-1,&sa,&sb);
(*ht)[sa].parent=i;
(*ht)[sb].parent=i;
(*ht)[i].lchild=sa;
(*ht)[i].rchild=sb;
(*ht)[i].weight=(*ht)[sa].weight+(*ht)[sb].weight;
}
print(ht);
printf("**HUFFMANCODE**/n");
for(i=1;i<=8;++i)
{
initstack(&sta);
z=i;
while((*ht)[i].parent!=0)
{
p=(*ht)[i].parent;
if((*ht)[p].lchild==i){push(&sta,0);}
if((*ht)[p].rchild==i){push(&sta,1);}
i=p;
}
i=z;
printf(" %3d :",(*ht)[i].weight);
pop(&sta);
}
printf("***************/n");
}
/*按表格输出结点的函数*/
void print(huffmantree *ht)
{
int i;
printf("*******TREE*******/n");
for(i=1;i<16;i++)
printf("%3d %2d %2d %2d/n",(*ht)[i].weight,(*ht)[i].parent,(*ht)[i].lchild,(*ht)[i].rchild);
printf("******************/n");
}
void main()
{
createhu(&htree,&hcode,weight,8);
}