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

大致思路

这里采用顺序存储的方式实现哈夫曼树,下面是大致的步骤
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;
}

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

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构与算法分析》实验报告 姓名 学号_ _____ __年 __月__ __日 上机题目:以静态链表为存储结构,编写给定权值{7,19,2,6,32,3}构造的 算法。 (输出以存储结构表示或以型显示(90度旋转)) 需求分析 1. 输入数据必须为int的整形数据,其数值范围为:-~47 2. 输出的数据格式为:%d 3. 测试数据的数据为:{7,19,2,6,32,3} 详细设计 1. 该程序采用顺序表的存储结构,其数据结构定义如下: #define n 6 #define m 2*n-1 #define max 100typedef struct {int data; int lchild,rchild,prnt; }hufmtree; 所用数据类型中每个操作的伪码算法如下: 创建哈 Program hufm(hufmtree t[m]) FOR i=0;i<m;i++ TO t[i].data=0; t[i].lchild=0; t[i].rchild=0; t[i].prnt=0; End FOR 输入结点值 FOR i=n;i<m;i++ TO p1=0;p2=0; small1=max;small2=max FOR j=0;j<=i-1;j++ TO IFt[j].prnt?=0 IF(t[j].data<small1) small2=small1; small1=t[j].data; p2=p1; p1=j;} ELSE IF(t[j].data<small2) small2=t[j].data; p2=j; t[p1].prnt=i+1; t[p2].prnt=i+1; t[i].lchild=p1+1; t[i].rchild=p2+1; t[i].data=t[p1].data+t[p2].data; END IF END FOR END Hufman 调试分析 1. 调试过程中主要遇到哪些问题?是如何解决的? 开始的时候main函数的数据结构类型定义的与主函数不同,而且缺少返回值,导致最 后的结果陷入死循环,通过看书,向同学询问,得以解决。 2. 经验和体会 哈又称最优二叉,此次实验创建哈算法,虽然依旧犯了不少错误,但 仍解决了。在其中学习了很多,对有了更深的了解。 测试结果 附件 见 058詹奇.Cpp ----------------------- 数据结构与算法分析实验报告全文共3页,当前为第1页。 数据结构与算法分析实验报告全文共3页,当前为第2页。 数据结构与算法分析实验报告全文共3页,当前为第3页。
是一种经典的数据结构,它用于压缩数据、编码和解码等方面。下面是用C语言实现构造的算法。 1. 定义哈节点的结构体: ```c struct huffman_node { int weight; // 权重 int parent; // 父节点的下标 int left; // 左子节点的下标 int right; // 右子节点的下标 }; ``` 其中,`weight`表示节点的权重,`parent`表示父节点的下标,`left`和`right`分别表示左右子节点的下标。 2. 构造的算法: ```c void huffman_tree(struct huffman_node *ht, int n) { int i, j, k; int min1, min2; for (i = 0; i < 2 * n - 1; i++) { ht[i].parent = -1; ht[i].left = -1; ht[i].right = -1; } for (i = 0; i < n; i++) { printf("请输入第%d个节点的权重:", i + 1); scanf("%d", &ht[i].weight); } for (i = 0; i < n - 1; i++) { min1 = min2 = INT_MAX; k = 0; for (j = 0; j < n + i; j++) { if (ht[j].parent == -1 && ht[j].weight < min1) { min2 = min1; min1 = ht[j].weight; k = j; } else if (ht[j].parent == -1 && ht[j].weight < min2) { min2 = ht[j].weight; } } ht[k].parent = n + i; ht[n + i].left = k; ht[n + i].right = -1; ht[n + i].weight = min1 + min2; k = 0; for (j = 0; j < n + i; j++) { if (ht[j].parent == -1 && ht[j].weight < min1) { min2 = min1; min1 = ht[j].weight; k = j; } else if (ht[j].parent == -1 && ht[j].weight < min2) { min2 = ht[j].weight; } } ht[k].parent = n + i; ht[n + i].right = k; } } ``` 该算法的主要思路是先输入每个节点的权重,然后依次构造的各个节点。具体的实现过程如下: - 首先,将哈的所有节点的父节点、左右子节点初始化为-1。 - 然后,输入每个节点的权重。 - 接着,依次构造的各个节点,直到构造完整个哈。具体的构造过程如下: - 找到权重最小的两个节点,分别作为新节点的左右子节点。 - 将新节点的权重设置为两个子节点的权重之和。 - 将新节点的父节点设置为原先没有父节点的节点中权重最小的节点。 3. 测试代码: ```c int main() { int n; printf("请输入节点的个数:"); scanf("%d", &n); struct huffman_node ht[2 * n - 1]; huffman_tree(ht, n); return 0; } ``` 该测试代码用于输入节点的个数,并调用前面实现的构造的算法。 希望这个算法能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值