#include
#include
#include
typedef struct
{
int weight;
int parent, lchild, rchild;
}HTNode, *HuffmanTree;
typedef char **HuffmanCode;
void Huffmancoding(HuffmanTree &HT, HuffmanCode &HC, int w[], int n);
void Select(HuffmanTree &HT, int n, int &a, int &b);
//求赫夫曼编码
void Huffmancoding(HuffmanTree &HT, HuffmanCode &HC, int w[], int n)
{
int m, i, start, f, c;
int s1, s2;
char *cd;
s1=s2=m=i=start=f=c=0;
//w存放n个字符的权值,构造赫夫曼树,并求出n个字符的赫夫曼编码,存放到HC
if(n<=1)
return;
m=2*n-1;
HT = (HuffmanTree)malloc((m)*sizeof(HTNode));
for(i=0; i
{
HT[i].weight = w[i];
HT[i].lchild = 0;
HT[i].rchild = 0;
HT[i].parent = 0;
}
for(i=n; i
{
HT[i].weight = 0;
HT[i].lchild = 0;
HT[i].rchild = 0;
HT[i].parent = 0;
}
//建赫夫曼树
for(i=n; i
{
//在HT[1..i-1]选择parent为且weight最小的两个结点,其序号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;
printf("%d-%d-%d-%d/n", HT[s1].weight, HT[s1].parent, HT[s1].lchild, HT[s1].rchild);
printf("%d-%d-%d-%d/n", HT[s2].weight, HT[s2].parent, HT[s2].lchild, HT[s2].rchild);
}
//从叶子到根逆向求每个节点的赫夫曼编码
HC = (HuffmanCode)malloc((n)*sizeof(char *));
cd = (char *)malloc(n*sizeof(char));
cd[n-1]='/0';
for(i=0; i
{
start = n-1;
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));
strcpy(HC[i], &cd[start]);
}
free(cd);
}
void Select(HuffmanTree &HT, int n, int &a, int &b)
{
int i;
int temp;
for(i=0; i<=n; i++)
if(HT[i].parent == 0)
a = i;
for(i=0; i<=n; i++)
if(HT[i].parent==0 && HT[i].weight
a=i;
for(i=0; i<=n; i++)
if(HT[i].parent==0 && i!=a)
b=i;
for(i=0; i<=n; i++)
if(HT[i].parent==0 && i!=a && HT[i].weight
b=i;
}
int main()
{
int i;
int w[8] = {23, 11, 5, 3, 29, 14, 7, 8};
int n = 8;
HuffmanTree ht;
HuffmanCode hc;
Huffmancoding(ht, hc, w, n);
for(i=0; i
printf("%s/n", hc[i]);
return 0;
}