哈弗曼树的带权路径长度

article/2025/10/2 13:10:32
最近刷题刷到了这一题,此题是北邮往年复试题,看了一些网上的讲解,大多数是方法比较复杂,有些巧妙的方法又往往却缺少解释,为了方便大家理解,给小伙伴们梳理梳理

题目描述:

哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。

输入描述:

输入有多组数据。
每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。

输出描述:

输出权值。

示例

输入:
5
1 2 2 5 9

输出:
37

解题分析:

哈夫曼树的构造方法相信大家肯定都是耳熟能详的。

根据哈弗曼树构造方法,我们不妨以 {1,2,2,5,9} 节点权值举例,根据上述方法我们可以构造出其哈夫曼树为如下:
Alt
由图我们可以很容易得到带权路径长度=
37 = 9 ∗ 1 + 5 ∗ 2 + 2 ∗ 3 + 2 ∗ 4 + 1 ∗ 4 ( 常 规 ) 37=9*1+5*2+2*3+2*4+1*4(常规) 37=91+52+23+24+14
这是我们在建立完树后的常见计算方法,但这种方法在计算机中可不方便直接得出,我们不妨看下面一个计算式子:
1 + 2 = 3 ,2 + 3 = 5,5 + 5 = 10, 10 + 9 = 19
我们发现
3 + 5 + 10 + 19 = 37 3+5+10+19 = 37 3+5+10+19=37
有点意思,巧合吗?不,不是,你不妨思考思考3、5、10、19这些数是怎么来的……没错,它们就是由节点权值而来。
我来替你分析分析,首先按照常规方法:9x1,而19 = 10 + 9,还剩下个10;再看常规中的5,它是5x2,而剩下的10中它又可以拆分为 5 + 5,(注意,这里的一个5是来自叶节点,另一个是来自非叶节点)而来自非叶节点的5 = 2 + 3;同样,2来自叶节点,3来自非叶节点;3 = 1 + 2,这下1和2都是来自叶节点。好了,这下19我们就已经分解完了,勤奋的你在草稿纸上比划比划,你有没有发现什么?

什么!没有?
你品,你细品,你细细品……

其实你把19,10,5,3都分解完后你会发现它们其实就是叶节点的加权和,你在求它们的时候其实就已经把我们常规方法中所考虑的深度因素带进去了。

那么,计算机用这种方法来求带权路径长度会不会简单呢?没错,非常简单,这里我们再考虑用priority_queue优先队列的数据结构,就更简单啦。如果不了解这种数据结构的话,推荐可以去查查STL库,你可以把他理解为一个有序(升或降)的容器(好用的工具我们一定要学会利用)

下面我给大家贴下我的代码,仅供参考。也希望大家能在理解了上面所描述的思想后再看

//哈弗曼树
#include <stdio.h>
#include <queue>
using namespace std;
// 哈弗曼树
int main(){priority_queue<int ,vector<int>, greater<int> > p;  // 这里规定是从小到大的优先队列,默认是从大到小// 默认形式:priority_queue<int> p;int n;while(scanf("%d",&n) != EOF){while(!p.empty())  // 清空队列p.pop();int val;for(int i=0;i<n;i++){scanf("%d",&val);p.push(val);}int sum = 0;  // 计算带权路径长度while(p.size() != 1){int a = p.top(); // 取出最小的数p.pop();int b = p.top(); // 取出次小的数p.pop();sum += a+b;p.push(a+b);}printf("%d\n",sum);}return 0;
} 

这道题就可以完美收工了,如果讲的有不足的地方欢迎大家指正。


http://chatgpt.dhexx.cn/article/ecZVhyCm.shtml

相关文章

哈夫曼树带权路径长度

一. 长什么样&#xff1f; 左边是普通树&#xff0c;右边是哈夫曼树 图a&#xff1a; WPL5*27*22*213*254 图b&#xff1a; WPL5*32*37*213*148 可见&#xff0c;图b的带权路径长度较小&#xff0c;我们可以证明图b就是哈夫曼树(也称为最优二叉树)。 二. 怎么生成和计算&…

哈夫曼树、带权路径长度、前缀编码 的概念

文章目录 一、基本概念1.1带权路径长度&#xff08;WPL&#xff09;1.2哈夫曼树 二、哈夫曼树的构造三、哈夫曼树的应用3.1哈夫曼编码与前缀编码 一、基本概念 1.1带权路径长度&#xff08;WPL&#xff09; 路径长度&#xff1a; 经历的边数 结点的带权路径长度&#xff1a; …

树学习(2)

1、 一颗哈夫曼树的带权路径长度等于其中所有分支结点的权值之和。&#xff08;错误&#xff09; 分析&#xff1a; 树的带权路径长度&#xff1a;定义为树中所有叶结点的带权路径长度之和&#xff1b;&#xff08;即等于所有结点&#xff08;叶结点分支结点&#xff0…

哈夫曼树 带权路径

树的带权路径长度 &#xff08;Weighted Path Length of Tree&#xff0c;简记为WPL&#xff09; 一般的&#xff0c;我们是可以用常规的构造哈夫曼树求带权路径长度。 计算结点的带权路径长度&#xff1a;结点到树根之间的路径长度与该结点上权的乘积。 带权路径长度WPL&a…

求Huffman树的带权路径长度

Huffman树的建立过程&#xff1a; 首先得到整个叶子结点的集合&#xff1a; 求Huffman树的带权路径长度算法&#xff1a; 书上讲常见的求Huffman树的带权路径长度算法为&#xff1a;从叶子结点权值乘路径长度&#xff1a; WPL7*25*25*23*32*349 另外一种求WPL的算法为&…

运行startx报错的解决

CentOS启动图形界面startx&#xff1a;xauth: file /root/.serverauth.1164 does not exist 运行如下命令 yum update yum groupinstall "X Window System" yum groupinstall "Desktop"报错无法解决问题. 继续运行如下命令 yum grouplist看到了一行: …

linux startx xinit

startx启动过程分析 startx 及xinit 介绍(经典) startx启动过程 startx用法&#xff1a; startx [ [ client ] options ... ] [ -- [ server ] [ display ] options ... ]startx三种启动方式&#xff1a; 1 指定client和server&#xff0c; 例如&#xff1a;startx /usr/bin…

startx 及xinit 介绍(经典)

X-server管理鼠标、键盘、显卡、显示器 X-client处理程序的运行 ---------------------------------------------------------------------------------------------------- WM管理窗口&#xff1a;移动、变型、关闭、装饰...... --------------------------------------------…

startx 及xinit 介绍

X-server管理鼠标、键盘、显卡、显示器X-client处理程序的运行----------------------------------------------------------------------------------------------------WM管理窗口&#xff1a;移动、变型、关闭、装饰......------------------------------------------------…

linux startx无效_startx命令_Linux startx 命令用法详解:用来启动X Window

startx命令用来启动X Window&#xff0c;实际上启动X Window的程序为xinit。 语法startx(参数) 参数客户端及选项&#xff1a;X客户端及选项&#xff1b; 服务器及选项&#xff1a;X服务器及选项。 实例 要在工作站上或 X 终端上启动 X 会话&#xff0c;请输入&#xff1a;star…

ubuntu 启动、退出 startx界面

使用的是ubuntu-focal 20.04 桌面版。因为在熟悉使用ubuntu出现这个问题。 启动startx 1、首先要了解ubuntu几种运行级&#xff08;参考init_百度百科&#xff09;&#xff0c;ubuntu桌面版默认启动的是init 5 &#xff1a;如下的正常登录界面。 2、进入和从terminal中输入s…

操作系统 - startx/xinit

了解startx/xinit 1.概述 用户可以通过 xinit 程序手动启动 Xorg 显示服务器&#xff0c;startx脚本是 xinit 的前端。 xinit 通常用在启动 X 时执行窗口管理器 或 桌面环境。虽然可以使用 xinit 在无窗口管理器的情况下启动图形程序&#xff0c;大部分图形程序都需要一个兼容…

CentOS 7输入startx无法启动图形化界面

【PS&#xff1a;最终解决方案见最后面】 【问题背景】 前两天在学习linux虚拟化的时候, 发现虚拟机磁盘空间不足, 由于当初分区的时候不是用lvm来分区的, 导致无法扩容, 所以只能新建了一台虚拟机来学习. 然而在新建完成后, 按照之前老师教的一系列优化手段, 将这台手段优化到…

6.1、startx命令怎么不能进入图形界面

命令行界面输入startx命令怎么不能进入图形界面^ ... [复制链接] 发表于 2010-1-29 12:55 | 来自 51CTO网页 [只看他] 楼主 我在虚拟机&#xff08;vmware&#xff09;上新安装的red hat linux 9.0在命令行界面输入startx命令怎么不能进入图形界面&#xff1f;&#xff1f;&…

Linux常用命令——startx命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) startx 用来启动X Window 补充说明 startx命令用来启动X Window&#xff0c;实际上启动X Window的程序为xinit。 语法 startx(参数)参数 客户端及选项&#xff1a;X客户端及选项&#xff1b;服务器及选项&a…

startx命令详解

startx命令来自于英文词组”start X-windows“的缩写&#xff0c;其功能是用于启动X-Windows系统。X-Windows System也被称为X或X11&#xff0c;中文译为X窗口系统&#xff0c;主要工作就是以图形方式显示软件窗口的系统&#xff0c;现在的GNOME和KDE桌面环境都是以X窗口系统为…

用gcc编译C++文件

我们误以为gcc只能用来编译C文件&#xff0c;这是不对的。 gcc也可以编译C文件&#xff0c;只是gcc不能自动联接C程序使用的库&#xff0c;即链接过程我们不能用gcc 而g实际上在编译C文件时也是使用gcc编译器&#xff0c;在链接时才使用g 例子1&#xff1a; #include <st…

gcc编译c++文件

gcc是编译c语言的&#xff0c;默认情况下&#xff0c;如果直接编译c程序&#xff0c;会报错&#xff1a; [rootserver demo2]# ls hello.cpp [rootserver demo2]# cat hello.cpp #include <iostream> using namespace std; int main(){ cout<<"hello,c&qu…

C++:GCC编译:GCC编译C++程序分步流程

C或者C程序从源代码生成可执行程序的过程&#xff0c;需要经历4个过程分别是&#xff1a;预处理&#xff0c;编译&#xff0c;汇编&#xff0c;链接。但考虑实际使用过程中&#xff0c;用户可能并不关心程序的执行结果&#xff0c;只是想快速得到最终的可执行程序&#xff0c;因…

如何使用GCC编译器

目录 : GCC rules开始...预编译编译汇编连接另外两个重要选项调试小结站点链接 摘要: 要想读懂本文&#xff0c;你需要对C语言有基本的了解&#xff0c;本文将介绍如何使用gcc编译器。 首先&#xff0c;我们介绍如何在命令行方式下使用编译器编译简单的C源代码。 然后&#x…