直接贴Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//节点数据结构
typedef struct
{
unsigned int weight;
unsigned int parent, lchild, rchild;
}HTNode, *HuffmanTree;
typedef char **HuffmanCode;
void select(HuffmanTree HT, int i, int &s1, int &s2) //选取现有节点中权重最小的两个数
{
int ni = 1;
while(HT[ni].parent != 0 && ni <= i)
{
ni++;
}
s1 = ni;
if(ni < i)ni++;
while(HT[ni].parent != 0 && ni <= i)
{
ni++;
}
s2 = ni;
if(HT[s1].weight > HT[s2].weight)
{
int tmp = s1;
s1 = s2;
s2 = tmp;
}
for(int p = ni+1; p <= i; ++p)
{
if(HT[s1].weight > HT[p].weight && HT[p].parent == 0)
{
s2 = s1;
s1 = p;
}
else if(HT[s2].weight > HT[p].weight && HT[p].parent == 0)
{
s2 = p;
}
}
}
//创建赫夫曼树
void BuildHuffmanTree(HuffmanTree &HT, int *w, int n)
{
if(n <= 1)return;
int m = 2 * n - 1;
HT = (HuffmanTree)malloc((m+1) * sizeof(HTNode));
HuffmanTree p = (HT+1);
int i;
for(p = HT+1, i = 1; i <= n; ++i, ++p, ++w) //初始化, 0号单元不用
{
p->weight = *w;
p->parent = 0;
p->lchild = 0;
p->rchild = 0;
}
for(; i <= m; ++i, ++p)
{
p->weight = 0;
p->parent = 0;
p->lchild = 0;
p->rchild = 0;
}
int s1, s2;
for(i = n+1; i <= m; ++i) //组建赫夫曼树
{
select(HT, i-1, s1, s2);
//printf("---%d %d\n", 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;
}
return;
}
//编码, 根据已创建的赫夫曼树进行编码
void HuffmanTreeCoding(HuffmanCode &HC, HuffmanTree &HT, int n)
{
HC = (HuffmanCode)malloc((n+1) * sizeof(char *));
int cdlen = 0;
char *cd = (char*)malloc(n * sizeof(char));
cd[n-1] = '\0';
for(int i = 1; i <= n; ++i)
{
int start = n -1;
int j = i;
int p = HT[i].parent;
//编码,从叶子节点逆推至树的根节点
do
{
if(HT[p].lchild == j) cd[--start] = '0';
else cd[--start] = '1';
j = p;
p = HT[p].parent;
}while(HT[j].parent != 0);
int len = n - start;
HC[i] = (char *)malloc( len *sizeof(char));
strcpy(HC[i], &cd[start]);
}
free(cd);
}
int main()
{
int n;
printf("请输入字符个数n = ");
scanf("%d", &n);
char ch[100];
int w[100];
printf("请输入字符和出现的频数:\n");
getchar();
for(int i = 0; i < n; i++)
{
scanf("%c %d", &ch[i], &w[i]);
getchar();
}
printf("输入成功!\n");
for(int i = 0; i < n; i++)
{
printf("%c: %d\n", ch[i], w[i]);
}
HuffmanTree HT;
BuildHuffmanTree(HT, w, n);
printf("构造赫夫曼树成功!\n");
for(int i = 1; i <= 2*n-1; i++)
{
printf("weight:%d parent:%d \n", HT[i].weight, HT[i].parent);
}
HuffmanCode HC;
HuffmanTreeCoding(HC, HT, n);
printf("编码成功!\n");
printf("字符的赫夫曼编码为:\n");
for(int i = 0; i < n; i++)
{
printf("%c: %s\n", ch[i], HC[i+1]);
}
system("pause");
}
test: