赫夫曼树,又称最优二叉树。它的最优体现在每个结点的权值与它的路径长度的乘积之和最小。具体定义参考博客:
https://blog.csdn.net/heart_love/article/details/50901943
赫夫曼树的构造原理非常简单,每次在当前的树中找到节点权值最小的两个节点分别作为左右子树,他们双亲的权值就是这两个左右孩子的权值之和。循环构造,直到生成一棵树。
赫夫曼编码就是在赫夫曼树的基础上,左边编码为0,右边为1,构成的二进制码值。
#include <stdio.h>
#include <string.h>
#define MAXVALUE 10000
typedef struct
{
char data;
int weight;
int parent;
int lchild;
int rchild;
int flag;
}HuffNode;
typedef struct
{
char code[10];
int start;
}HuffCode;
HuffNode H[9];
HuffCode HC[5]; //当有n个结点需要构造赫夫曼树时,总共需要2*n-1个节点
int select (HuffNode *H, int n) //选出当前树中的最小值
{
int min = MAXVALUE, i, j;
for(i = 0; i <= n; i++)
{
if(H[i].weight < min && H[i].flag == -1)
{
min = H[i].weight;
j = i;
}
}
H[j].flag = 1;
return j;
}
void HuffTreeInit (HuffNode *H, int n)
{
int i;
for(i = 0; i < n; i++)
{
H[i].data = getchar();
scanf("%d", &(H[i].weight));
getchar();
H[i].flag = -1;
H[i].lchild = -1;
H[i].parent = -1;
H[i].rchild = -1;
}
for(; i < 2*n-1; i++)
{
H[i].flag = -1;
H[i].lchild = -1;
H[i].parent = -1;
H[i].rchild = -1;
}
}
void CreatHuffTree (HuffNode *H, int n)
{
int i, l, r;
for(i = n; i < 2*n-1; i++)
{
l = select(H, i-1); //分别选出当前树中的最小的俩个权值,构造成二叉树
r = select(H, i-1);
H[l].parent = i;
H[r].parent = i;
H[i].weight = H[l].weight+H[r].weight;
H[i].lchild = l;
H[i].rchild = r;
}
}
void PrintHuffTree (HuffNode *H, int n) //将构造好的赫夫曼树(最优二叉树)层序遍历
{
HuffNode list[2*n-1];
int in, out;
in = out = 0;
list[in++] = H[2*n-2];
while(in > out)
{
printf("%d\n", list[out].weight);
if(list[out].lchild != -1)
{
list[in++] = H[list[out].lchild];
list[in++] = H[list[out].rchild];
}
out++;
}
}
void CreatHuffCode (HuffNode *H, HuffCode *HC, int n) //赫夫曼编码,从每个节点开始,向上编码
{
int i, c, f;
HuffCode d;
for(i = 0; i < n; i++)
{
d.start = n+1;
c = i;
f = H[c].parent;
while(f != -1) //一直编码,知道结点为根节点
{
if(H[f].lchild == c)
{
d.code[--d.start] = '0';
}
else
{
d.code[--d.start] = '1';
}
c = f;
f = H[c].parent;
}
HC[i] = d;
}
}
void PrintHuffCode (HuffNode *H, HuffCode *HC, int n)
{
int i, j;
for(i = 0; i < n; i++)
{
printf("data:%c ", H[i].data);
for(j = HC[i].start; j < n+1; j++)
{
printf("%c", HC[i].code[j]);
}
printf("\n");
}
}
int main ()
{
HuffTreeInit(H, 5);
CreatHuffTree(H, 5);
CreatHuffCode (H, HC, 5) ;
PrintHuffCode(H, HC, 5);
// PrintHuffTree(H, 5);
return 0;
}