哈夫曼树
1创建哈夫曼树
struct HTNode
{
int weight;
int parent;
int left_child;
int right_child;
};
void select_Min(struct HTNode * HT ,int length, int * e1, int * e2)
{
int min1, min2;
min1 = min2 = INT_MAX;
int pos1, pos2;
pos1 = pos2 = 0;
for(int i = 1; i < length + 1; ++i)
{
if (HT[i].parent == 0)
{
//!parent==0说明在森林中
if(HT[i].weight < min1)
{
min2 = min1;
pos2 = pos1;
min1 = HT[i].weight;
pos1 = i;
}
else if (HT[i].weight < min2)
{
min2 = HT[i].weight;
pos2 = i;
}
}
}
*e1 = pos1;
*e2 = pos2;
}
//构造哈夫曼树
void createHuffmanTree(struct HTNode ** HT, int n)
{
//1初始化
if (n <= 1)
return;
int m = 2 * n - 1;
*HT = (struct HTNode *) malloc(sizeof (struct HTNode) * (m + 1));
for (int i = 1; i <= m; i++)
{
(*HT)[i].left_child = 0;
(*HT)[i].right_child = 0;
(*HT)[i].parent = 0;
}
for (int i = 1; i <= n; i++)
{
printf("输入第 %d 个结点的权重:", i);
fflush(stdout);
scanf("%d", &(*HT)[i].weight);
}
//2建立哈夫曼树
int s1, s2;
for (int i = n+1; i <= m; i++)
{
select_Min(*HT, i - 1, &s1, &s2);
(*HT)[s1].parent = i;
(*HT)[s2].parent = i;
(*HT)[i].left_child = s1;
(*HT)[i].right_child = s2;
(*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight;
}
}
2哈夫曼编码
void huffmanCoding(struct HTNode ** HT, char *** HC, int n)
{
int start;
int f;
int c;
char * cd;
*HC = (char **) malloc(sizeof (char *) * (n + 1));
cd = (char *) malloc(sizeof (char) * n);
cd[n-1] = ' ';
for (int i = 0; i <= n; ++i)
{
start = n - 1;
c = i;
f = (*HT)[i].parent;
while (f != 0)
{
if ((*HT)[f].left_child == c)
cd[--start] = '0';
else
cd[--start] = '1';
c = f;
f = ((*HT)[f].parent);
}
(*HC)[i] = (char *) malloc(sizeof (char ) * (n - start));
strcpy((*HC)[i], &cd[start]);
}
free(cd);
}
3测试
#include
#include
#include
#include
#define NODES 8
int main()
{
struct HTNode * T;
char ** HC;
createHuffmanTree(&T, NODES);
for(int i = 1; i < 2 * NODES; ++i)
{
printf("%dtweight = %dtparent = %dtleft_child=%dtright_child=%dn",
i, T[i].weight, T[i].parent, T[i].left_child, T[i].right_child);
}
huffmanCoding(&T, &HC, 8);
int a = 65;
for (int i = 1; i <= NODES; i++)
{
printf("%c = %sn", a, HC[i]);
a++;
}
return 0;
}