#include "string.h"
#include "conio.h"
#include "malloc.h"
#include <stdio.h>
#define N 10 /*待编码字符的个数,即树中叶结点的最大个数*/
#define M 2*N-1 /*树中总的结点数目*/
typedef struct{
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree; /*树中结点的结构*/
typedef char **HuffmanCode;
int w[]={5,29,7,8,14,23,3,11};
char data[]={'a','b','c','d','e','f','g','h'};
void Select(HTNode ht[],int k,int *s1,int *s2){
/*ht[1…k]中选择parent为,并且weight最小的两个结点
其序号由指针变量s1,s2指向*/
int i;
for (i=1;i<=k && ht[i].parent!=0 ;i++);
*s1=i;
for (i=1;i<=k;i++)
if (ht[i].parent==0 && ht[i].weight<ht[*s1].weight) *s1=i;
for (i=1; i<=k ; i++)
if (ht[i].parent==0 && i!=*s1) break;
*s2=i;
for (i=1;i<=k;i++)
if ( ht[i].parent==0 && i!=*s1 && ht[i].weight<ht[*s2].weight) *s2=i;
}
void HuffmanCoding(HuffmanTree &ht,HuffmanCode &hc,int n){
/*构造Huffman树ht,并求出n个字符的编码*/
//先生成n棵二叉树
int i,j,m,c,f,s1,s2,start;
m=2*n-1;//总节点数
ht=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
for (i=1;i<=m;i++){
if (i<=n) ht[i].weight=w[i-1];
else ht[i].weight=0;
ht[i].parent=ht[i].lchild=ht[i].rchild=0;
}
//哈夫曼算法
for(i=n+1;i<=m;i++){
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;
}
hc=(HuffmanCode)malloc((n+1)*sizeof(char *));
char *cd=(char *)malloc(n*sizeof(char));
cd[n-1]='/0';
for (i=1;i<=n;i++) {
start=n-1;
for (c=i,f=ht[i].parent;f;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));
strcpy(hc[i],&cd[start]);
}
free(cd);
}
void main()
{
HuffmanTree ht;
HuffmanCode hc;
int n=8;
HuffmanCoding(ht,hc,n);
for(int i=1;i<=n;i++)
printf("%c:%s/n",data[i-1],hc[i]);
printf("/n");
}