当前位置:网站首页>哈夫曼树(最优二叉树)
哈夫曼树(最优二叉树)
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;
}边栏推荐
- Video game design report template and
- How vscode debug nodejs
- Overview of dobesie wavelet (DB wavelet function) in wavelet transform
- Intelligent operation and maintenance scenario analysis: how to detect abnormal business system status through exception detection
- Self join usage of SQL
- Summary of Baimian machine learning
- DDD based on ABP -- Entity creation and update
- Simple encapsulation of wechat applet wx.request
- Atcoder beginer contest 261e / / bitwise thinking + DP
- Learning and thinking about the relevant knowledge in the direction of building network security knowledge base
猜你喜欢

Under multi data source configuration, solve org.apache.ibatis.binding Bindingexception: invalid bound statement (not found) problem

Production environment tidb cluster capacity reduction tikv operation steps

Meaning of 7 parameters of thread pool

Video game design report template and resources over the years

Simple understanding and implementation of unity delegate

LeetCode高频题56. 合并区间,将重叠的区间合并为一个区间,包含所有区间

Overview of dobesie wavelet (DB wavelet function) in wavelet transform

使用 Fiddler Hook 报错:502 Fiddler - Connection Failed

DS binary tree - maximum distance of binary tree nodes

Vector introduction and underlying principle
随机推荐
Activate the newly installed Anaconda in the server
spark学习笔记(三)——sparkcore基础知识
DDD based on ABP -- Entity creation and update
Date processing bean
Use of keywords const, volatile and pointer; Assembly language and view of register status
Conversion of timestamp and time in Excel
C language large and small end mode judgment function
spark:获取日志中每个时间段的访问量(入门级-简单实现)
Research Summary / programming FAQs
Usage differences of drop, truncate and delete
DS diagram - the shortest path of the diagram (excluding the code framework)
JS native - array sorting to find out the characters with the largest number of strings
Mysql库的操作
老虎口瀑布:铜梁版小壶口瀑布
Video game design report template and
spark:指定日期输出相应日期的日志(入门级-简单实现)
Discussion on the basic use and address of pointer in array object
Self join usage of SQL
PrestoUserError: PrestoUserError(type=USER_ERROR, name=INVALID_FUNCTION_ARGUMENT, message=“Escape st
VSCode如何调试Nodejs