头文件
#include<dos.h>
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
定义结构体
typedef struct
{
unsigned int weight;
unsigned int parent, lchild, rchild;
}HTNode,*HuffmanTree;
typedef char** HuffmanCode;
在HT【1……t】中选择权值最小结点
int minpoint(HuffmanTree HT, int n)
{
int i;
int min;
int min_weight=32767;
for (i = 1; i <= n; i++)
{
if (HT[i].weight < min_weight && HT[i].parent == 0)
{
min_weight = HT[i].weight;
min = i;
}
}
HT[min].parent = 1;
return min;
}
从HT数组的前k个元素中选出weight最小且parent为0的元素,并将该元素的序号返回
void select(HuffmanTree HT, int n, int &s1, int &s2)
{
s1 = minpoint(HT, n);
s2 = minpoint(HT, n);
}
构造一棵赫夫曼树
void CreatHaffmantree(HuffmanTree& HT, unsigned int* w, int n)
{
int i, m;
int s1, s2;
HuffmanTree p;
if (n <= 1)
return;
m = 2 * n - 1;
HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode));
if (HT == NULL)
{
printf("\n分配内存失败!\n");
return;
}
p = HT + 1;
for (i = 1;i <= n;++i, ++p, ++w)
{
p->weight = *w;
p->parent = 0;
p->lchild = 0;
p->rchild = 0;
}
for (;i <= m;++i, ++p)
{
p->weight = 0;
p->lchild = 0;
p->rchild = 0;
p->parent = 0;
}
printf("\n初始化完成\n");
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;
}
printf("\n创建哈夫曼树结束!\n");
}
将有n个叶子节点的哈夫曼树编码,将所编码存放于HC中
void huffmancoding(HuffmanTree HT, HuffmanCode& HC, int n)
{
int i, c, f, start;
char* cd;
HC = (HuffmanCode)malloc((n + 1) * sizeof(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 != 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 printhuffmantree(HuffmanCode HC, unsigned int* w, int n)
{
int i;
printf("\nHuffmanCode is:\n");
for (i = 1;i <= n;i++)
{
printf("%3d---", w[i - 1]);
puts(HC[i]);
}
printf("\n");
printf("\n完成哈夫曼编码表的输出!\n");
}
主函数
int main()
{
HuffmanTree HT;
HuffmanCode HC;
int n, i;
unsigned int* w;
char j = 'y';
while (j != 'N' && j != 'n')
{
printf("\n\t构造哈夫曼树.\n");
printf("\n\t首先输入叶子结点数目.\n");
printf("\n\t然后输入每个叶子结点的权值.\n");
printf("\n\t程序会构造一棵哈夫曼树并显示哈夫曼编码.\n");
printf(" 5---0110\n 29---10\n 7---1110\n 8---1111\n 14---110\n");
printf(" 23---00\n 3---0111\n 11---010\n");
printf("\n请输入叶子结点数目:\n");
scanf("%d", &n);
if (n <= 1)
{
printf("\n该数不合理!\n");
exit(1);
}
w = (unsigned int*)malloc(n * sizeof(unsigned int));
printf("\n请输入各叶子结点的权值:\n");
for (i = 0;i < n;i++)
scanf("%d", &w[i]);
printf("\n权值输入结束!\n");
CreatHaffmantree(HT, w, n);
huffmancoding(HT, HC, n);
printhuffmantree(HC, w, n);
printf("\n哈夫曼树构造完毕,还要继续吗?(Y/N)\n");
scanf(" %c", &j);
}
}
运行结果
哈夫曼树示意图