#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
// 哈夫曼树结点结构
typedef struct {
int weight; // 结点权重
int parent, left, right;
} HTNode, *HuffmanTree;
// 函数声明
void CreateHuffmanTree(HuffmanTree *HT, int *w, int n);
void Select(HuffmanTree HT, int end, int *s1, int *s2);
// 查找两个权重最小的节点
void Select(HuffmanTree HT, int end, int *s1, int *s2)
{
*s1 = *s2 = 0;
int min1 = INT_MAX, min2 = INT_MAX; // 初始化最小值
for (int i = 1; i <= end; i++)
{
if (HT[i].parent == 0)
{ // 只考虑未被选中的节点
if (HT[i].weight < min1)
{
min2 = min1; // 更新第二小
*s2 = *s1;
min1 = HT[i].weight; // 更新最小
*s1 = i;
}
else if (HT[i].weight < min2)
{
min2 = HT[i].weight; // 更新第二小
*s2 = i;
}
}
}
}
// 创建哈夫曼树
void CreateHuffmanTree(HuffmanTree *HT, int *w, int n) {
if (n <= 1) return; // 如果是一个编码就是0
int m = 2 * n - 1; // 哈夫曼的总结点数
*HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode)); // 修改分配内存的方式
// 初始化所有的结点
for (int i = 1; i <= n; i++) {
(*HT)[i].weight = w[i - 1]; // w的指针从0开始
(*HT)[i].parent = 0;
(*HT)[i].left = 0;
(*HT)[i].right = 0;
}
// 初始化非叶子结点
for (int i = n + 1; i <= m; i++) {
(*HT)[i].weight = 0;
(*HT)[i].parent = 0;
(*HT)[i].left = 0;
(*HT)[i].right = 0;
}
// 创建Huffman树
for (int i = n + 1; i <= m; i++) {
int s1, s2;
Select(*HT, i - 1, &s1, &s2); // 查找算法
(*HT)[s1].parent = i;
(*HT)[s2].parent = i;
(*HT)[i].left = s1;
(*HT)[i].right = s2;
(*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight;
}
}
//测试函数
void TestHuffmanTree() {
int weights[] = {5, 9, 12, 13, 16, 45};
int n = sizeof(weights) / sizeof(weights[0]);
HuffmanTree HT;
CreateHuffmanTree(&HT, weights, n); // 创建哈夫曼树
//输出哈夫曼树节点信息
for (int i = 1; i <= 2 * n - 1; i++)
{
cout << "Node " << i << ": ";
cout << "Weight = " << HT[i].weight << ", ";
cout << "Parent = " << HT[i].parent << ", ";
cout << "Left = " << HT[i].left << ", ";
cout << "Right = " << HT[i].right << endl;
}
free(HT); //释放分配的内存
}
int main()
{
TestHuffmanTree(); // 测试哈夫曼树
return 0;
}
HuffmanTree的创建与查找操作
于 2024-08-08 18:08:32 首次发布