文章目录
大致思路
这里采用顺序存储的方式实现哈夫曼树,下面是大致的步骤
1.初始化哈夫曼树
2.找到两个权值最小且没有父亲的节点
3.根据这两个最小的节点,构造节点,构造n-1次
以权值为{ 2, 3, 8, 11, 99, 32, 64, 82 }的数组构造哈夫曼树为例
初始化时:
节点下标 | weight | parent | leftChild | rightChild |
---|---|---|---|---|
1 | 2 | 0 | 0 | 0 |
2 | 3 | 0 | 0 | 0 |
3 | 8 | 0 | 0 | 0 |
4 | 11 | 0 | 0 | 0 |
5 | 99 | 0 | 0 | 0 |
6 | 32 | 0 | 0 | 0 |
7 | 64 | 0 | 0 | 0 |
8 | 82 | 0 | 0 | 0 |
9 | 0 | 0 | 0 | 0 |
10 | 0 | 0 | 0 | 0 |
11 | 0 | 0 | 0 | 0 |
12 | 0 | 0 | 0 | 0 |
13 | 0 | 0 | 0 | 0 |
14 | 0 | 0 | 0 | 0 |
15 | 0 | 0 | 0 | 0 |
构造哈夫曼树后:
节点下标 | weight | parent | leftChild | rightChild |
---|---|---|---|---|
1 | 2 | 9 | 0 | 0 |
2 | 3 | 9 | 0 | 0 |
3 | 8 | 10 | 0 | 0 |
4 | 11 | 11 | 0 | 0 |
5 | 99 | 14 | 0 | 0 |
6 | 32 | 12 | 0 | 0 |
7 | 64 | 13 | 0 | 0 |
8 | 82 | 14 | 0 | 0 |
9 | 5 | 10 | 1 | 2 |
10 | 13 | 11 | 9 | 3 |
11 | 24 | 12 | 4 | 10 |
12 | 56 | 13 | 11 | 6 |
13 | 120 | 15 | 12 | 7 |
14 | 181 | 15 | 8 | 5 |
15 | 301 | 0 | 13 | 14 |
头文件包含和类型定义
头文件包含
#include<stdlib.h>
#include<stdio.h>
哈夫曼树节点的结构
typedef struct
{
int weight;
int parent;
int leftChild;
int rightChild;
}HTNode;
哈夫曼树的结构
typedef struct
{
HTNode* node;
int count;
}HuffmanTree;
node
是指向节点数组的指针
count
是哈夫曼树节点的个数
构造哈夫曼树
1.找两个最小权值节点函数
void FindTwoMinNode(HuffmanTree* tree, int cur, int* min1, int* min2)
{
int s1 = 0;
int s2 = 0;
for (int i = 1; i < cur; i++)
{
if (tree->node[i].parent == 0)
{
s1 = i;
break;
}
}
for (int i = 1; i < cur; i++)
{
if (tree->node[i].parent == 0 &&
tree->node[i].weight < tree->node[s1].weight)
{
s1 = i;
}
}
for (int j = 1; j < cur; j++)
{
if (tree->node[j].parent == 0 && s1 != j)
{
s2 = j;
break;
}
}
for (int i = 1; i < cur; i++)
{
if (tree->node[i].parent == 0 &&
tree->node[i].weight < tree->node[s2].weight &&
tree->node[i].weight > tree->node[s1].weight)
{
s2 = i;
}
}
*min1 = s1;
*min2 = s2;
}
2.构造哈夫曼树函数
void CreateHuffmanTree(HuffmanTree* tree, int weights[], int n)
{
//初始化
tree->node = (HTNode*)malloc(sizeof(HTNode) * 2 * n);
tree->count = 2 * n - 1;
for (int i = 1; i <= n; i++)
{
tree->node[i].weight = weights[i - 1];
tree->node[i].parent = 0;
tree->node[i].leftChild = 0;
tree->node[i].rightChild = 0;
}
for (int i = n + 1; i <= 2 * n - 1; i++)
{
tree->node[i].weight = 0;
tree->node[i].parent = 0;
tree->node[i].leftChild = 0;
tree->node[i].rightChild = 0;
}
//构造
for (int i = n + 1; i < 2 * n; i++)
{
int min1 = 0;
int min2 = 0;
FindTwoMinNode(tree, i, &min1, &min2);
tree->node[i].weight = tree->node[min1].weight + tree->node[min2].weight;
tree->node[i].leftChild = min1;
tree->node[i].rightChild = min2;
tree->node[min1].parent = i;
tree->node[min2].parent = i;
}
}
3.打印函数
void PrintHuffman(HuffmanTree* tree)
{
printf("%-10s %-10s %-10s %-10s\n", "weight", "parent", "left", "right");
for (int i = 1; i < tree->count + 1; i++)
{
printf("%-10d %-10d %-10d %-10d\n", tree->node[i].weight,
tree->node[i].parent,
tree->node[i].leftChild,
tree->node[i].rightChild);
}
}
4.主函数
int main()
{
HuffmanTree tree;
int weights[8] = { 2, 3, 8, 11, 99, 32, 64, 82 };
CreateHuffmanTree(&tree, weights, 8);
PrintHuffman(&tree);
return 0;
}
运行结果: