当前位置:网站首页>哈夫曼树(最优二叉树)
哈夫曼树(最优二叉树)
2022-07-24 15:07:00 【柘木木】
哈夫曼树(最优二叉树):树的带权路径长度最小(树的带权路径是指根节点到各个叶子结点的步长*权值之和),这样的二叉树是哈夫曼树,又叫做最优二叉树。
引入一个情景:将n堆果子堆成一堆,每堆一次消耗掉同等果子质量的体力,求怎么堆这些果子,使得消耗的体力最小,这样的问题就是一颗哈夫曼树,其叶子结点就是果子的质量(就像一个个果堆堆在最后面),非叶子结点就是其子结点质量之和,即消耗的体力,根节点就是果子质量之和,即果堆的质量,因为每次合并两个果子消耗两个果堆的质量,所以最后消耗的体力就是各个非叶子结点之和。
由此可见,这样的情景下的二叉树树不止一颗,因为叶子结点的父结点的左右孩子是可以交换的,所以可以有多颗哈夫曼树,但是树的最小带权路径肯定是唯一的,因为建造哈夫曼树都是最小的两个合并,有点贪心算法的意思,每一步最小从而达到结果最小。
哈夫曼树的特性:不存在度数为1的结点(度数,其子结点的个数),权值越高的结点越靠近根节点。
构造哈夫曼树:
思路:反复选择两个最小的元素,合并,直到只剩下一个元素,使用优先队列(即堆结构)来实现
例题:
合并果子
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。
因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。
例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。
所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
输入
输入包括两行,第一行是一个整数n(1<=n<=10000),表示果子的种类数。
第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。
输出
输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于2^31。
样例输入 Copy
3 1 2 9
样例输出 Copy
15
代码:
//哈夫曼树的建立;
#include<iostream>
#include<queue>
using namespace std;
priority_queue<long long , vector<long long >, greater<long long> > q;//优先队列
//优先队列的知识:优先队列是用堆实现的
//可以通过greater这样优先级设定来实现内部排序,long long 是队列内的元素类型,vector<long long >是优先队列底层heap实现的容器;
int main ( ){
int n;
long long temp, x, y,ans = 0;
scanf("%d", &n);
for(int i = 0; i < n; i++) {
scanf("%lld", &temp);
q.push(temp);
}
while(q.size() > 1) {//哈夫曼树的建立,队内两最小值两两合并,直到只剩一个元素;
x = q.top( );//priority_queue只能用top访问优先最高的队首元素,不能使用front和back访问;
q.pop( );
y = q.top( );
q.pop( );
q.push(x + y);//合并;
ans += x + y;
}
printf("%lld", ans);
return 0;
}边栏推荐
- Kotlin类与继承
- 打假Yolov7的精度,不是所有的论文都是真实可信
- Which securities company is the best and safest to open an account? How to open an account and speculate in stocks
- JS native - array sorting to find out the characters with the largest number of strings
- PIP source switching
- AG. DS binary tree -- hierarchical traversal
- 文件操作详解
- 基于ABP实现DDD--实体创建和更新
- onBlur和onChange冲突解决方法
- Caffe framework and production data source for deep learning
猜你喜欢

Leetcode · daily question · 1184. distance between bus stops · simulation

Deep learning 1 perceptron and implementation of simple back propagation network

Unity uses NVIDIA flex for unity plug-in to realize the effects of making software, water, fluid, cloth, etc. learning tutorial

【USENIX ATC'22】支持异构GPU集群的超大规模模型的高效的分布式训练框架Whale

Number of bytes occupied by variables of type char short int in memory

Grpc middleware implements grpc call retry

Error when using Fiddler hook: 502 Fiddler - connection failed

Outlook tutorial, how to set rules in outlook?

Meaning of 7 parameters of thread pool

Discussion and legitimacy of the order of entering and leaving the stack
随机推荐
Leetcode-09 (next rank + happy number + full rank)
How vscode debug nodejs
华为无线设备配置WPA2-802.1X-AES安全策略
DS graph - minimum spanning tree
Discussion and legitimacy of the order of entering and leaving the stack
Under multi data source configuration, solve org.apache.ibatis.binding Bindingexception: invalid bound statement (not found) problem
老虎口瀑布:铜梁版小壶口瀑布
The sliding window of Li Kou "step by step" (209. The smallest sub array, 904. Fruit baskets)
DS binary tree - parent and child nodes of binary tree
pytorch with torch.no_grad
zabbix管理员忘记登录密码
《Route planning method for UAV in unknown environment based on improved SAS algorithm》翻译
Can you buy 6% of financial products after opening a stock account?
LeetCode高频题56. 合并区间,将重叠的区间合并为一个区间,包含所有区间
【OpenCV 例程300篇】238. OpenCV 中的 Harris 角点检测
Mysql库的操作
Decrypt "sea Lotus" organization (domain control detection and defense)
Detailed explanation of address bus, data bus and control bus
Leetcode high frequency question 56. merge intervals, merge overlapping intervals into one interval, including all intervals
SQL的SELF JOIN用法