#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 20
#define M 2*N-1
typedef struct Huffman{
int weight;
int parent;
int lchild;
int rchild;
}huf_node,huf_tree[M+1];
typedef char* huf_code[N+1];
void select(huf_tree ht,int k,int* a,int* b){
int i;
int mi=9999,mii=9999;
for(i=1;i<=k;i++){
if(ht[i].parent==0){
if(ht[i].weight<mi){
mi=mii;
mii=ht[i].weight;
*a=*b;
*b=i;
}
if(ht[i].weight<mii){
mii=ht[i].weight;
*b=i;
}
}
}
}
void create(huf_tree ht,int w[],int n){
int i;
for(i=1;i<=n;i++){
ht[i].lchild=0;
ht[i].rchild=0;
ht[i].parent=0;
ht[i].weight=w[i];
}
int m=2*n-1;
for(i=n+1;i<=m;i++){
ht[i].lchild=0;
ht[i].parent=0;
ht[i].rchild=0;
ht[i].weight=0;
}
for(i=n+1;i<=m;i++){
int a,b;
select(ht,i-1,&a,&b);
ht[i].weight=ht[a].weight+ht[b].weight;
ht[a].parent=i;ht[b].parent=i;
ht[i].lchild=a;ht[i].rchild=b;
}
printf("哈夫曼树的终态:\n");
for(i=1;i<=2*n-1;i++){
printf("%d %d %d %d\n",ht[i].weight,ht[i].parent,ht[i].lchild,ht[i].rchild);
}
}
void cre_huf_code(huf_tree ht,huf_code hc,int n){
char* cd;
cd=(char*)malloc(n*sizeof(char));
cd[n-1]='\0';
int i;
for(i=1;i<=n;i++){
int start=n-1;
int c=i;int p=ht[i].parent;
while(p!=0){
start--;
if(ht[p].lchild==c) cd[start]='0';
else cd[start]='1';
c=p;p=ht[p].parent;
}
hc[i]=(char*)malloc((n-start)*sizeof(char));
strcpy(hc[i],&cd[start]);
}
free(cd);
}
void visit_huf_code(huf_code hc,int n){
int i,k;
printf("各个叶子结点的哈夫曼编码:\n");
for(i=1;i<=n;i++){
for(k=0;*(hc[i]+(k*sizeof(char)))!='\0';k++){
printf("%c",*(hc[i]+(k*sizeof(char))));
}
printf("\n");
}
}
int main(){
huf_tree ht;
int i,n,w[N];
printf("请输入叶子结点个数:");
scanf("%d",&n);
printf("请输入各个叶子结点的权值:");
for(i=1;i<=n;i++){
scanf("%d",&w[i]);
}
create(ht,w,n);
huf_code hc;
cre_huf_code(ht,hc,n);
visit_huf_code(hc,n);
return 0;
}