【数据结构】【c语言】哈夫曼树的构造

本文详细介绍使用顺序存储方式构建哈夫曼树的过程,并通过具体数值示例展示节点的构造和更新过程。从初始化到逐步合并节点,最终形成完整的哈夫曼树。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大致思路

这里采用顺序存储的方式实现哈夫曼树,下面是大致的步骤
1.初始化哈夫曼树
2.找到两个权值最小且没有父亲的节点
3.根据这两个最小的节点,构造节点,构造n-1次

以权值为{ 2, 3, 8, 11, 99, 32, 64, 82 }的数组构造哈夫曼树为例

初始化时:

节点下标weightparentleftChildrightChild
12000
23000
38000
411000
599000
632000
764000
882000
90000
100000
110000
120000
130000
140000
150000

构造哈夫曼树后:

节点下标weightparentleftChildrightChild
12900
23900
381000
4111100
5991400
6321200
7641300
8821400
951012
10131193
112412410
125613116
1312015127
141811585
1530101314

头文件包含和类型定义

头文件包含

#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;
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值