哈夫曼树 例题

假设某棵二叉树有N个叶结点。给定这些叶结点的权值,求所有可能的二叉树中带权路径长度(WPL)的最小值。

注:

  1. 结点的带权路径长度(WPL):结点的权值乘以该结点的深度(假设根节点的深度为0);
  2. 二叉树的带权路径长度(WPL):二叉树中所有叶结点的带权路径长度之和。

输入描述

每个输入文件中一组数据。

第一行是一个整数N(2<=N<=100),表示叶结点的个数。

第二行为用空格隔开的N个不超过1000的正整数(不保证唯一),表示所有叶结点的权值。

输出描述

输出一个正整数,表示最小带权路径长度。

样例1

输入

5

16 30 21 10 12

输出

200

思路:

构建一颗哈夫曼树,然后dfs遍历求带权路径,我感觉这样应该是最小的

下面是我模仿的代码(错的)

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>//to_string(value)
#include<cstdio>
#include<cmath>
#include<vector>//res.erase(unique(res.begin(), res.end()), res.end())
#include<queue>
#include<stack>
#include<map>
#include<set>//iterator,insert(),erase(),lower/upper_bound(value)/find()return end()
#define ll long long
using namespace std;
int a[110];
bool cmp(int k1, int k2) {return k1 > k2;
}
typedef struct Tree {int data;struct Tree* lc;struct Tree* rc;
}tree;
vector<tree*>nm;
int dfs(tree* tr, int l) {if (tr == NULL) {return 0;}else if (tr->lc == NULL && tr->rc == NULL) {return tr->data * l;}return dfs(tr->lc, l + 1) + dfs(tr->rc, l + 1);
}
signed main() {int n;cin >> n;for (int i = 0; i < n; i++) {cin >> a[i];}sort(a, a + n, cmp);for (int i = 0; i < n; i++) {tree* T;T = new tree;T->data = a[i];T->lc = NULL;T->rc = NULL;nm.push_back(T);}while (nm.size() != 1) {tree* T, * T1, * T2;T1 = nm.back();nm.pop_back();T2 = nm.back();nm.pop_back();T = new tree;T->data = T1->data + T2->data;T->lc = T1;T->rc = T2;nm.push_back(T);}tree* head;head = nm.back();cout << dfs(head, 0);
}

输出结果:

208

我输出的树

 题目可能要求的树

 我参考的代码

#include <cstdio>
#include <queue>
#include <vector>
using namespace std;vector<int> vi;struct node {int v;node* left = nullptr;node* right = nullptr;
};struct cmp {// 优先队列排序规则按权值最小的放队首bool operator()(const node* a, const node* b) {return a->v > b->v;}
};int dfs(node* root, int l) {if (root == nullptr) return 0;if (root->left == nullptr && root->right == nullptr) {return root->v * l;   // 返回叶节点的带权路径长度} else {return dfs(root->left, l + 1) + dfs(root->right, l + 1);    // 左右子树的递归结果之和}
}int getWpl() {priority_queue<node*, vector<node*>, cmp> q;// 将所有叶节点加入队列for (int i = 0; i < vi.size(); i++) {node* t = new node();t->v = vi[i];     // 叶节点t->left = nullptr;t->right = nullptr;q.push(t);}// 每次合并两个最小权值节点while(q.size() != 1) {node* a = q.top();q.pop();node* b = q.top();q.pop();node* t = new node();t->v = a->v + b->v; // 新节点权值之和t->left = a;      // 关联左孩子t->right = b;     // 关联右孩子q.push(t);      // 新节点入队}node* root = q.top(); // 构建出的二叉树根节点return dfs(root, 0);    // 计算wpl
}int main() {int n, x;scanf("%d", &n);for (int i = 0; i < n; i++) {scanf("%d", &x);vi.push_back(x);}printf("%d\n", getWpl());return 0;
}

下面是chatGPT给我的思路

二叉树的带权路径长度(Weighted Path Length,WPL)是指所有叶子节点的权值乘以它们到根节点的路径长度之和。带权路径长度最小值是指在所有可能的二叉树中,WPL最小的那个二叉树。 计算二叉树的带权路径长度最小值可以使用哈夫曼树算法。哈夫曼树是一种特殊的二叉树,它的叶子节点是给定的权值,每个非叶子节点的权值是其左右子树权值之和。哈夫曼树的带权路径长度最小,因此可以用来计算二叉树的带权路径长度最小值。 具体算法如下: 1. 将所有节点按照权值从小到大排序,构造n棵只有一个节点的二叉树。 2. 从这n棵二叉树中选择两棵权值最小的二叉树,合并成一棵新的二叉树,新的二叉树的根节点权值为两棵子树的权值之和。 3. 将新的二叉树插入到原来的二叉树集合中,删除原来的两棵子树。 4. 重复步骤2和3,直到只剩下一棵二叉树为止。 5. 计算这棵二叉树的带权路径长度,即为二叉树的带权路径长度最小值。 时间复杂度为O(nlogn),其中n为节点数。

第二遍写发现问题所在

我忘记在vector中对新建的树的大小进行比较

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>//to_string(value)
#include<cstdio>
#include<cmath>
#include<vector>//res.erase(unique(res.begin(), res.end()), res.end())
#include<queue>
#include<stack>
#include<map>
#include<set>//iterator,insert(),erase(),lower/upper_bound(value)/find()return end()
#define ll long long
using namespace std;
int a[110];
bool cmp(int k1, int k2) {return k1 > k2;
}
typedef struct Tree {int data;struct Tree* lc;struct Tree* rc;
}tree;
vector<tree*>nm;
int dfs(tree* tr, int l) {if (tr == NULL) {return 0;}else if (tr->lc == NULL && tr->rc == NULL) {return tr->data * l;}return dfs(tr->lc, l + 1) + dfs(tr->rc, l + 1);
}
bool cmp1(tree *k1,tree *k2){return k1->data>k2->data;
}
signed main() {int n;cin >> n;for (int i = 0; i < n; i++) {cin >> a[i];}sort(a, a + n, cmp);for (int i = 0; i < n; i++) {tree* T;T = new tree;T->data = a[i];T->lc = NULL;T->rc = NULL;nm.push_back(T);}while (nm.size() != 1) {tree* T, * T1, * T2;T1 = nm.back();nm.pop_back();T2 = nm.back();nm.pop_back();T = new tree;T->data = T1->data + T2->data;T->lc = T1;T->rc = T2;nm.push_back(T);sort(nm.begin(),nm.end(),cmp1);}tree* head;head = nm.back();cout << dfs(head, 0);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/40926.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

svn更新/提交代码提示错误 , 进行清理下“破除写锁操作“

1.如果svn提交或者更新代码有--进行清理下"破除写锁操作"--此提示,一般情况下右键,然后选择进行确定就可以 2.如果还不行的话,在项目下的 .svn 文件夹里面新建文件夹,命名为tmp,然后重新更新,提交,就会发现问题解决了

2022年深圳杯数学建模A题代码思路-- 破除“尖叫效应”与“回声室效应”,走出“信息茧房”

问题重述&#xff1a; 在全新的信息传播格局下&#xff0c;如何破除“尖叫效应”与“回声室效应”&#xff0c;走出“信息茧房”&#xff0c;是当前迫切需要解决的现实问题&#xff0c;即如何从信息传输的顶层设计、推荐算法的公平性和广大网络用户的责任担当等方面&#xff0…

钉钉最新点赞破除限制方法(

我不是标题党&#xff01; 首先&#xff0c;放图片&#xff08;&#xff08;&#xff08; 时间这里是录视频的时间&#xff0c;2021-8-27&#xff0c;不是标题党&#xff01; 上方法&#xff01; 主要原理&#xff1a;利用抓包抓到的点赞api端口&#xff0c;实现持续点击或…

亚马逊云科技 Build On -Serverless低代码平台初体验-快速完成vue前端订单小程序

文章目录 一、我所认识的低代码平台二、Serverless的使用场景三、拖拉跩实现build on 的Serverless1. 使用图像界面创作方法2. 拖拉跩模块实现搭建3. 实时测试流程是否正确4. 最终的设计和流程图 四、创建端到端的基于vue的前端图形化界面六、总结与活动链接 一、我所认识的低代…

一小段Python代码,破解加密zip文件的密码

Python 有一个内置模块 zipfile 可以解压 zip 压缩包。先来测试一波&#xff1a;创建一个测试文件&#xff0c;压缩&#xff0c;设置解压密码为123。 import zipfile# 创建文件句柄 file zipfile.ZipFile("测试.zip", r) # 提取压缩文件中的内容&#xff0c;注意密码…

开源治理工具选一个

随着开源技术在云计算、大数据、AI领域的不断运用&#xff0c;不断破除技术壁垒&#xff0c;让企业快速建立自身的应用&#xff0c;在开源软件基础一&#xff0c;自主研发部分代码&#xff0c;便可以推出企业自身品牌的产品&#xff0c;开源技术的应用极大的推动了云计算、大数…

机器人微控制器编程(CoCube)-破除定势

从课程到生活&#xff1b; 从书本到理想&#xff1b; 从程序到生态&#xff1b; 从个体到集群&#xff1b; 从特殊到一般&#xff1b; 从传统到现代&#xff1b; 从技术到科学&#xff1b; 从理论到工程&#xff1b; 从基础到高阶。 …… 课程归根结底&#xff0c;是为学生服务…

复制浏览器html代码吗,网页文字不能直接复制?只需简单几招即可轻松破除限制,想学吗?...

原标题&#xff1a;网页文字不能直接复制&#xff1f;只需简单几招即可轻松破除限制&#xff0c;想学吗&#xff1f; 想必大家在网上都遇到这样的问题&#xff0c;网页文字受到限制无法直接复制&#xff0c;这该如何是好呢&#xff1f; 既不想登录注册又想直接复制走内容&#…

LR低代码快速开发平台 高效调整企业组织架构

组织架构以及围绕组织架构的设计、实施和变革&#xff0c;是企业管理永恒的话题&#xff0c;它上承公司的业务战略和运营模式&#xff0c;下接业务流程和信息系统建设&#xff0c;重要性不言而喻。数字化变革浪潮之下&#xff0c;商业模式的颠覆、价值链的重塑都需要由相匹配的…

自己动手写编译器:通过语法编译构建语法树并实现中间代码生成

上一节我们手动构造了语法树&#xff0c;然后调用各个节点实现中间代码生成。语法树的构建由语法解析完成&#xff0c;本节我们要完成语法解析逻辑&#xff0c;在语法解析过程中构造语法树&#xff0c;然后再像上一节那样实现中间代码生成。 这里我们再次回顾一下左递归&#…

安卓原神QQ机器人搭建教程

1&#xff0c;下载安装Termux 下载地址&#xff1a;https://f-droid.org/packages/com.termux/ 滑到下面点击这个 2&#xff0c;打开Termux&#xff0c;安装Ubuntu 安装模拟权限git&#xff0c;python&#xff0c;执行下面命令 pkg install proot git python -y 3&#xff…

如何在windows电脑上完成原神签到、祈愿抽卡分析等功能

一款开源的游戏辅助工具——原神助手。支持原神签到、祈愿抽卡分析、查看便签状态和游戏详细数据等。 开发者自述也是偶然间接触到《原神》&#xff0c;于是一发不可收拾&#xff0c;爱上这款游戏了。 在游戏中&#xff0c;如果要查看角色信息等内容&#xff0c;就必须需要登…

不同服务器的ps4账号吗,原神PC与PS4互通数据吗 不同平台数据互通分析

原神最近上线了pc版本&#xff0c;那么&#xff0c;你知道PC与PS4互通吗&#xff1f;这是很多玩家关心的问题&#xff0c;不同的平台&#xff0c;数据能否互通呢&#xff1f;比如说&#xff0c;不同平台是否可以一起玩&#xff0c;不同平台帐号是否可以切换&#xff0c;下面就为…

如何在 Mac 上玩原神?简单三步流畅运行

该方法也是本人一点点摸索出来的&#xff0c;花了很久&#xff0c;已经帮大家踩过坑了&#xff0c;该方法是最简单方便的&#xff0c;而且画质高、运行流畅&#xff0c;甘雨姐姐我来了~ 注意此方法只支持 M 系列芯片 一、安装 playCover github 源码地址 &#xff1a;https:/…

指令微调数据集整理

文章目录 开源指令数据集斯坦福数据链家数据Baize(基于少量种子问题的对话数据) 垂直领域数据集医疗领域的英文数据医疗领域的中文数据法律领域中文数据 COIG数据集&#xff08;可商用的中文数据集&#xff09; 开源指令数据集 斯坦福数据 斯坦福52K英文指令数据&#xff1a;…

Linux下使用Samba做域控

AI画妹子的工作先暂告一段落。毕竟戗行也是要有门槛的。 企业中使用Windows Server使用活动目录集中管理PC、服务器是很成熟的方案。突然想到&#xff0c;如果有一天出于某种原因不再使用微软方案了&#xff0c;AD该如何替代&#xff1f;问了一下chatGPT&#xff0c;它说&…

LINUX下设置postgresql的登录密码

1、postgresql登录密码主要是修改2个方向&#xff1a;首先用户有密码&#xff0c;其次是在配置文件中设置登录的限制参数 2、修改密码&#xff1a; alter role postgres with password Postgres; 提示面修改完成 3、修改配置文件pg_hub.conf,在IPV4下或者本地local下&#x…

获取 Panabit Linux 版 root 密码

面包多 - Panabit - root 密码重置工具https://mbd.pub/o/bread/mbd-Y5yTk5hx 可以重置 Panabit Linux 版本的 root 密码&#xff0c;直接获取 root 权限。 下载并在 Panabit 应用商店手动安装后就能看到列表中有新增 root 密码重置工具 打开 工具页面就可以对 root 密码进行重…

PostgreSQL数据库设置登录数据库密码

PostgreSQL数据库安装完以后会默认创建一个管理员的账号postgres用户&#xff0c;默认登录时是不需要密码验证就可以直接登录的 修改用户登录认证密码有两种方式&#xff1a; 1、用命令行的sql语句来进行修改 登录到PostgreSQL数据库里 [rootnode1 ~ 10:51:32]# su postgres b…

phpMyAdmin中config.inc.php设置密码和修改密码的方法

phpMyAdmin有3种授权模式&#xff1a; 1. cookie: 显示一个web登录页面&#xff0c;输入mysql的用户名和密码&#xff0c;然后进入管理界面。 $cfg[Servers][$i][auth_type] cookie; /* Server parameters */ $cfg[Servers][$i][host] localhost; $cfg[Servers][$i][connect_…