数据结构_哈夫曼树及哈夫曼编码

本文详细介绍了哈夫曼树的概念、构造过程及其在数据结构中的应用。通过贪心策略构建最优二叉树,并展示了哈夫曼编码的思想,确保高频字符编码短。同时提供了哈夫曼树和编码的代码实现,包括测试数据的处理。
摘要由CSDN通过智能技术生成

huffman树

哈夫曼树又称最优树。是一类带权路径长度最短的树

路径:树中从一个结点到另一个结点之间的分支构成的路径
路径长度:路径上分支的数目
树的路径长度:从树根到每一个结点的路径长度之和
:赋予实体的一个量,对实体某个或某些属性的数值化。在数据结构中有结点权和边权。
结点的带权路径长度:该结点到根的路径长度和权值的乘积
树的带权路径长度(WPL):树中所有叶子结点的带权路径长度之和
哈夫曼树:存在m个权值{w1,w2…wm},可以构造一棵含n个叶子结点,每个结点的权值为wi的二叉树,且其中树的带权路径长度最小的二叉树被称为最优二叉树或哈夫曼树
下图的c图为哈夫曼树
在这里插入图片描述

哈夫曼树的构造

根据定义可知,WPL等于各个结点的路径长度和权值的乘积。要想WPL最小,那么如果保证了权值大的,它的路径长度设定小,乘积才会小,由此由各个结点保证为最小值来确定总体的最优解,是一种贪心法(局部最优解的集合代替整体最优解)。

构造思路:
(1)根据给定的n个权值{w1, w2,…, wn},构造一个有n棵只有对应权值根结点的二叉树的森林。
(2)在森林中选取两棵根结点的权值最小的树作为左右子树合并成一棵二叉树,且置新的二叉树的根结点的权值为其左、右子树上根结点的权值之和。
(3)重复(2),直到森林只含一棵树为止。这棵树便是哈夫曼树。
在这里插入图片描述

代码实现

核心函数实现

void Creat_huffman(Huffman_tree &T,int n) {
   
	void  Select(Huffman_tree T, int n, int& s1, int& s2); //选择最小权值
	if (n <= 1)
		return;
	int m = 2 * n;             
	T = new Hnode[m];                   //1~n存储初始的森林,n~2n-1存储新生成树的头结点
	for (int i = 1; i < m; ++i) {
          // 初始化
		T[i].parent = 0;
		T[i].lchild = 0;
		T[i].rchild = 0;
	}
	for (int i = 1; i <= n; ++i) {
         //输入m个权值构成森林
		printf("输入第%d个结点的值\n", i);
		scanf_s("%d", &T[i].data);
	}
	for (int i = n+1; i < m; ++i) {
         //生成新的树
		int s1, s2;
		Select(T, i, s1, s2); 
		T[i].lchild = s1;
		T[i].rchild = s2;
		T[i].data = T[s1].data + T[s2].data;printf("%d,%d,  %d\n", s1, s2,T[i].data);

		T[s1].parent = T[s2].parent = i;
	}
}

void Select(Huffman_tree T, int n, int& s1, int& s2) {
   
	int min, min1, m;
	min = min1 = m = 0;

	for (int i = 1; i < n; ++i)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值