堆的实现-适用于算法竞赛

news2025/2/22 17:16:50

首先讲一下能够实现的操作。

  1. 插入一个数
  2. 查找最小值
  3. 删除最小值
  4. 删除任意一个元素
  5. 修改任意一个元素

什么是堆?

堆其实是一棵完全二叉树。

即处理叶子节点和倒数第一层节点,其他节点都有两个子节点,而且顺序是从上到下,从左到右。

小根堆:每个节点都满足小于等于左右儿子节点。

堆有down和up操作。

何为down?

何为up?

操作

插入一个数heap[++size]=x;up(size)在尾部插入,后维护
查找最小值head[1];
删除最小值heap[1]=heap[size];size--;down(1)
删除任意一个元素heap[k]=heap[size];size--;down(k);up(k)
修改一个元素heap[k]=x;down(k);up(k)

例题:
 

输入一个长度为 𝑛 的整数数列,从小到大输出前 𝑚 小的数。

输入格式

第一行包含整数 𝑛 和 𝑚。

第二行包含 𝑛 个整数,表示整数数列。

输出格式

共一行,包含 𝑚 个整数,表示整数数列中前 𝑚 小的数。

数据范围

1≤m≤n≤1e5,1≤𝑚≤𝑛≤1e5,
1≤数列中元素≤1e9,1≤数列中元素≤1e9

输入样例:
5 3
4 5 1 3 2
输出样例:
1 2 3

代码:

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e6+10;
int heap[N],idx;
void down(int u){
    int t =u;//假设t是在此节点和其左右儿子节点中最小的,初始时将t赋值为u(此节点)。
    if(2*u<=idx && heap[2*u]<heap[t]) t = 2*u;
    if(2*u+1 <= idx && heap[2*u+1]<heap[t]) t = 2*u+1;
    if(u != t){
        swap(heap[u],heap[t]);
        down(t);
    }
}

int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    idx=n;
    for(int i=1;i<=n;i++){
        scanf("%d",&heap[i]);
    }
    
    for(int i=n/2;i>=1;i--){
        down(i);
    }
    
    while(m--){
        printf("%d ",heap[1]);
        heap[1]=heap[idx];
        idx--;
        down(1);
    }
    
    return 0;
}

单独拿出down和up操作

down:

void down(int u){
    int t =u;//假设t是在此节点和其左右儿子节点中最小的,初始时将t赋值为u(此节点)。
    if(2*u<=idx && heap[2*u]<heap[t]) t = 2*u;
    if(2*u+1 <= idx && heap[2*u+1]<heap[t]) t = 2*u+1;
    if(u != t){
        swap(heap[u],heap[t]);
        down(t);
    }
}
//注意u是当前节点,在堆上的索引,idx是当前已经用的索引的个数(相当于每个元素的身份证编号,从小到大开始编号)。
//2*u表示当前节点u的左儿子节点的身份证号,heap[2*u]表示左儿子节点的值。2*u<=idx表示存在左儿子,
//因为如果计算出来的身份证编号比现在有的最大的编号还大,就说明计算出来的编号不存在。

up:

void up(int u){
    while( u/2 >0 && heap[u] < heap[u/2]){
        swap(heap[u],heap[u/2]);
        u=u/2;
    }
}
//u/2表示当前节点u的父节点的编号,一个节点只有一个父节点

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C# 简单的单元测试

文章目录 前言参考文档新建控制台项目新建测试项目添加引用添加测试方法测试结果(有错误)测试结果&#xff0c;通过正规的方法抛出异常 总结 前言 听说复杂的项目最好都要单元测试一下。我这里也试试单元测试这个功能。到时候调试起来也方便。 参考文档 C# 单元测试&#xf…

JavaFX布局-TilePane

JavaFX布局-TilePane 常用属性alignmenttileAlignmentorientationhgapvgappadding 实现方式Javafxml 自动排列其子节点成网格状根据容器的大小以及子节点的数量和大小自动计算最佳的排列方式推荐子节点固定大小&#xff0c;参差不齐的子节点&#xff0c;效果很诡异 常用属性 …

【VS2019安装+QT配置】

【VS2019安装QT配置】 1. 前言2. 下载visual studio20193. visual studio2019安装4. 环境配置4.1 系统环境变量配置4.2 qt插件开发 5. Visual Studio导入QT项目6. 总结 1. 前言 前期安装了qt&#xff0c;发现creator编辑器并不好用&#xff0c;一点都不时髦。在李大师的指导下&…

基于Springboot的高校毕业生资格审查系统/计算机项目/Java、Web/课设

摘 要 计算机网络与信息化管理相配合&#xff0c;可以有效地提高管理人员的工作效能和改进工作的质量。良好的高校毕业生资格审查系统可以使管理员工作得到更好的管理和应用&#xff0c;并有助于管理员更好地管理高校毕业生资格审查&#xff0c;并有助于解决人力管理中出现的差…

C++第二十八弹---进一步理解模板:特化和分离编译

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1. 非类型模板参数 2. 模板的特化 2.1 概念 2.2 函数模板特化 2.3 类模板特化 2.3.1 全特化 2.3.2 偏特化 2.3.3 类模板特化应用示例 3. …

Redis常用指令(不定期更新)

Redis常用指令&#xff08;不定期更新&#xff09; 查询指定前缀key的数量查看键空间事件开启键空间通知 查询指定前缀key的数量 查询【TEST前缀】的key数量 EVAL "return #redis.call(keys,TEST:*)" 0返回信息 查看键空间事件 config get notify-keyspace-even…

Linux——DNS服务搭建

&#xff08;一&#xff09;搭建nginx 1.首先布置基本环境 要求能够ping通外网&#xff0c;有yum源 2.安装nginx yum -y install nginx 然后查看验证 3.修改网页配置文件 修改文件&#xff0c;任意编写内容&#xff0c;然后去物理机测试 &#xff08;二&#xff09;创建一…

51.TFT_LCD液晶屏驱动设计与验证(4)

&#xff08;1&#xff09;顶层文件&#xff1a; module tft_colorbar(input clk ,input reset_n ,output hsync ,output vsync ,output [23:0] rgb_tft ,output tft_bl ,output …

Python多进程环境同时操作时如何互斥操作

title: Python多进程环境同时操作时如何互斥操作 tags: [互斥, python] categories: [Python, 多进程] 在 Python 中&#xff0c;fcntl 模块提供了对文件控制操作的接口&#xff0c;包括文件锁定。fcntl.flock() 函数用于对文件进行锁定&#xff0c;以确保在多进程环境中对文件…

接口自动化测试框架实战-1-项目环境搭建

上一小节中我们讲解了一下本次接口自动化测试框架的大致架构设计和功能概览&#xff0c;本小节我们讲解一下整个项目开发环境的搭建方法。 1、python基础环境 安装python3版本&#xff1a;建议3.9.6版本及以上即可 新建项目的虚拟环境&#xff1a;virtualenv或者pycharm自带的…

MyBatis的入门操作--打印日志和增删改查(单表静态)

下面介绍注解和xml实现crud的操作 目录 一、日志打印和参数传递 1.1.使用mybatis打印日志 1.2.参数传递细节 二、crud&#xff08;注解实现&#xff09; 2.1.增(insert) 2.2.删(delete) 和 (update) 2.3.查(select) 三、crud&#xff08;xml实现&#xff09; 3.1.准备…

环境搭建-Windows系统搭建Docker

Windows系统搭建Docker 一、系统虚拟化1.1 启用虚拟化2.2 启用Hyper-v并开启虚拟任务 三、安装WSL3.1 检验安装3.2 安装WSL 四、Docker安装4.1 Docker安装包下载4.2 Docker安装4.3 运行docker Desktop 五、Docker配置5.1 打开Docker配置中心5.2 配置Docker国内镜像 六、使用 一…

WIN7系统安装,BIOS+MBR方式

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

【数据结构初阶】单链表经典算法题十二道——得道飞升(中篇)

hi&#xff0c;bro—— 目录 5、 链表分割 6、 链表的回文结构 7、 相交链表 8、 环形链表 【思考】 —————————————— DEAD POOL —————————————— 5、 链表分割 /* struct ListNode {int val;struct ListNode *next;ListNode(int x) : val(x), …

C++编程: 使用 Nanomsg 进行 PUB-SUB 模式基准测试

文章目录 0. 引言1. Nanomsg简介1.1 可扩展性协议类型1.2 支持的传输机制1.3 NanoMsg 架构与实现 2. PUB-SUB 模式基准测试 0. 引言 Nanomsg 作为一款高性能的通信库&#xff0c;支持多种消息传递模式&#xff0c;其中包括 PUB-SUB&#xff08;发布-订阅&#xff09;。 本篇文…

【NPU 系列专栏 2.4 -- 高速互连 NVLink 详细介绍】

请阅读【嵌入式及芯片开发学必备专栏】 文章目录 NVLink 简介NVLink 主要特点NVLink 应用场景NVLink 工作原理NVLink 实例介绍DL 中使用 NVLinkHPC 中使用 NVLinkSummaryNVLink 简介 NVLink 是 NVIDIA 开发的一种高速互连技术,旨在提升 GPU 与 GPU 之间以及 GPU 与 CPU 之间的…

simapro碳捕集

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…

SpringBoot整合阿里云短信业务

详细介绍SpringBoot整合阿里云短信服务的每一步过程&#xff0c;同时会将验证码存放到Redis中并设置过期时间&#xff0c;尽量保证实战的同时也让没做过的好兄弟也能实现发短信的功能~ 1. 注册阿里云账号和创建Access Key 首先&#xff0c;你需要注册一个阿里云账号&#xff0…

【轨物方案】电表红外抄表物联网装置

对于光伏运维工程师来说&#xff0c;电表抄表是一件并不陌生的工作&#xff0c;不过很多并网电表的RS485通讯接口一般都被占用了&#xff0c;并且电表的外壳也被铅封起来。在这种情况下电站通常采用人工抄表的方式采集电量数据&#xff0c;这种方式费时费力&#xff0c;对电站运…

【研发日记】Matlab/Simulink技能解锁(十)——PID调参技巧

文章目录 前言 项目背景 参数P调节 参数I调节 参数D调节 整体优化 分析和应用 总结 参考资料 前言 见《【研发日记】Matlab/Simulink技能解锁(五)——七个Simulink布线技巧》 见《【研发日记】Matlab/Simulink技能解锁(六)——六种Simulink模型架构》 见《【研发日记】…