////////////////////////////////////////////
//哈夫曼树算法 模式匹配 //
//Author:Wang Yong //
//Date: 2010.8.19 //
////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#define MAX 100000
#define N 100
////////////////////////////////////////////
//定义哈夫曼树的根结点类型
typedef struct //根据哈夫曼树的2N-1特点,采用顺序存储表示
{
int weight; //根节点的全知
int parrent,lchild,rchild;//结点的双亲,孩子的位置
} HuffmTree;
////////////////////////////////////////////
//哈夫曼树编码的每个结点类型
typedef struct
{
char code[N]; //存放当前的哈夫曼编码
int start; //输出起始位置
}HCode;
////////////////////////////////////////////
//构造哈夫曼树, n为初始森林中的结点数
void CreatHuffmTree(HuffmTree tree[],int n)
{
if(n <= 1) return; //少于一个结点,则独立成为一个哈夫曼树
int i;
for(i = 1; i <= 2*n-1; i++) //将tree[i]赋初始值
{
tree[i].weight = 0;
tree[i].lchild = tree[i].rchild = tree[i].parrent = -1;
}
int w;
for(i = 1 ; i <= n ; i++) //将初始的n个结点赋值权值
{
scanf("%d",&w);
tree[i].weight = w;
}
int j;
for(i = n+1; i <= 2*n-1;i++ ) //构造HuffmTree
{
int min1 , min2;
min1 = min2 = MAX;
int l,r;
l = r = -1;
for(j = 1; j <= i-1;j++) //每次合并之后多出一个根节点,放入其中
{
if(tree[j].parrent == -1 && tree[j].weight < min1)//选择合并的左孩子结点
{
min2 = min1;
r = l;
min1 = tree[j].weight;
l = j;
}
else if(tree[j].parrent == -1 && tree[j].weight < min2)//选择合并的右孩子结点
{
min2 = tree[j].weight;
r = j;
}
}
tree[i].weight = tree[l].weight + tree[r].weight;
tree[l].parrent = tree[r].parrent = i;
tree[i].lchild = l;tree[i].rchild = r;
}
}
///////////////////////////////////////////////////////////////
//哈夫曼编码
void CreatHCode(HuffmTree tree[],HCode cd[],int n)
{
HCode hfmcd;
int i,j,c,p;
for(i = 1 ; i <= n;i++)
{
hfmcd.start = n;
c = i;
p = tree[c].parrent;
while(p != -1)
{
if (c == tree[p].lchild)
hfmcd.code[hfmcd.start--] = '0';
else if(c == tree[p].rchild)
hfmcd.code[hfmcd.start--] = '1';
c = p;
p = tree[p].parrent;
}
hfmcd.start++;
for(j = hfmcd.start ; j <= n ; j++)
cd[i].code[j] = hfmcd.code[j];
cd[i].start = hfmcd.start;
}
}
//////////////////////////////////////////////////////////////
int main()
{
int i,j;
int n;
printf("请输出初始结点个数:");
scanf("%d",&n);
HuffmTree tree[2*n];
HCode cd[n+1];
CreatHuffmTree(tree,n);
CreatHCode(tree,cd,n);
for(i = 1 ; i <= n; i++)
{
for(j = cd[i].start; j <= n;j++)
printf("%c",cd[i].code[j]);
printf("\n");
}
return 0;
}