堆排序(小根堆模板)

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

输入格式

第一行包含整数 n 和 m。

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

输出格式

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

数据范围

1≤m≤n≤10^5,
1≤数列中元素≤10^9

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

堆排序分为大根堆和小根堆,这里实现的是小根堆,定义是父节点比它的左右孩子的值都要小。

堆排序主要实现两个操作:down和up,把最小值调整到根节点,把最大值调整到最下面

堆排序的五种操作:

 

示例代码:

#include<iostream>
#include<algorithm>
using namespace std;

const int N=1e5+10;

int n,m;
int h[N],Size;  //h表示堆,size表示堆的大小

void down(int u)  //小根堆核心,向下比较,使父节点小于左右孩子
{
    int t=u;  //让t作为最小值
    if(u*2 <= Size && h[u*2] < h[t]) t=u*2; //左儿子存在且左儿子小于父节点,左儿子就是t
    if(u*2+1 <= Size && h[u*2+1] < h[t]) t=u*2+1; //右儿子更小,右儿子就是t
    if(u != t)  //如果父节点不是最小的
    {
        swap(h[u],h[t]); //和最小的交换,使父节点最小
        down(t); //对父节点与子节点中最小的位置(也就是刚刚交换完之后,原来的父节点现在所在的位置)进行递归向下操作,直到这个节点满足小根堆性质
    }
}
int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>h[i];
    Size=n;
    
    for(int i=n/2;i;i--) down(i); //堆排序,只需要对倒数第二层及上面的元素排序即可(有子节点的点),最下面的没有子节点进行比较,就不用进行down操作
    
    while(m--)
    {
        cout<<h[1]<<" ";  //按顺序从小到大输出,最小的就是根节点
        h[1]=h[Size]; //用最后的元素覆盖第一个
        Size--; //删除最后一个点
        down(1); //对第一个元素进行堆排序
    }
    return 0;
}

 

 关于down函数:
void down(int u)  //小根堆核心,向下比较,使父节点小于左右孩子
{
    int t=u;  //让t作为最小值
    if(u*2 <= Size && h[u*2] < h[t]) t=u*2; //左儿子存在且左儿子小于父节点,左儿子就是t
    if(u*2+1 <= Size && h[u*2+1] < h[t]) t=u*2+1; //右儿子更小,右儿子就是t
    if(u != t)  //如果父节点不是最小的
    {
        swap(h[u],h[t]); //和最小的交换,使父节点最小
        down(t); //对父节点与子节点中最小的位置(也就是刚刚交换完之后,原来的父节点现在所在的位置)进行递归向下操作,直到这个节点满足小根堆性质
    }
}

如果没有发生交换,说明父子节点都满足堆的性质(父节点最小),如果交换了,则意味着下面的所有点也要跟着变化,所以是对发生了交换的父节点(现在父子里面最小的成了父节点,而原来的父节点到了子节点的位置,这里是指原来的父节点) 进行递归操作,直到这个交换的父节点和它下面的子节点都满足堆的性质。

关于for循环堆排序的解释:
for(int i=n/2;i;i--) down(i); //堆排序,只需要对倒数第二层及上面的元素排序即可(有子节点的点),最下面的没有子节点进行比较,就不用进行down操作

因为堆排是对父节点和它的两个子节点排序,所以没有子节点的点就不用堆排,堆是一个完全二叉树,有子节点的点下标从1到n/2,n是节点总数。 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Centos8上部署Zabbix5.0

1.关闭Selinux及防火墙&#xff0c;避免Web页面无法访问。 setenforce 0 vim /etc/selinux/config 修改“SELINUX”等号后的内容为disabled SELINUXdisabled\\关闭并关闭开机自启 systemctl stop firewalld systemctl disable firewalld 2.配置Centos8本地yum源。 mkdir /mn…

『MySQL快速上手』-⑦-内置函数

文章目录 1.日期函数1.1 获得年月日1.2 获得时分秒1.3 获得时间戳1.4 在日期的基础上加日期1.5 在日期的基础上减去时间1.6 计算两个日期之间相差多少天案例1案例22.字符串函数案例3.数学函数4.其他函数1.日期函数 1.1 获得年月日

基于Python美化图片亮度和噪点

支持添加噪点类型包括&#xff1a;添加高斯噪点、添加椒盐噪点、添加波动噪点、添加泊松噪点、添加周期性噪点、添加斑点噪点、添加相位噪点&#xff0c;还提供清除噪点的功能。 我们先看一下实测效果&#xff1a;&#xff08;test.jpg为原图&#xff0c;new.jpg为添加后的图片…

Rust结构体的定义和实例化

1.结构体特点 Rust的结构体跟元组类型比较类似,它们都包含多个相关的值。和元组一样&#xff0c;结构体的每一部分可以是不同类型。但不同于元组&#xff0c;结构体需要命名各部分数据以便能清楚的表明其值的意义。由于有了这些名字&#xff0c;结构体比元组更灵活&#xff1a…

浅谈二叉树

✏️✏️✏️今天给大家分享一下二叉树的基本概念以及性质、二叉树的自定义实现&#xff0c;二叉树的遍历等。 清风的CSDN博客 &#x1f61b;&#x1f61b;&#x1f61b;希望我的文章能对你有所帮助&#xff0c;有不足的地方还请各位看官多多指教&#xff0c;大家一起学习交流&…

【CUDA编程--编程模型简介算子开发流程】

官方文档&#xff1a;https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html 什么是CUDA CUDA全称&#xff08;Compute Unified Device Architecture&#xff09;统一计算架构&#xff0c;是NVIDIA推出的并行计算平台深度学习加速&#xff1a;对于神经网络&…

无线通信测量仪器-4945B/C 无线电通信综合测试仪

01 4945B/C 无线电通信综合测试仪 产品综述&#xff1a; 4945B/4945C无线电通信综合测试仪是多功能、便携式无线电综合测试类仪器&#xff0c;基于软件无线电架构&#xff0c;集成了跳频信号发生与分析、矢量信号发生与解调分析、模拟调制信号发生与解调分析、音频信号发生与…

C语言求数组中出现次数最多的元素

一、前言 遇到一个需求&#xff0c;需要求数组中出现次数最多的元素&#xff0c;查找了一些资料&#xff0c;结合自己的思路&#xff0c;编写了程序并验证。 只考虑元素为非负整数的数组&#xff0c;如果有出现次数相同的元素&#xff0c;则返回较小元素。 二、编程思路 以数…

python3+requests+unittest实战系列【二】

前言&#xff1a;上篇文章python3requestsunittest&#xff1a;接口自动化测试&#xff08;一&#xff09;已经介绍了基于unittest框架的实现接口自动化&#xff0c;但是也存在一些问题&#xff0c;比如最明显的测试数据和业务没有区分开&#xff0c;接口用例不便于管理等&…

AI主播“败走”双11,想用AI省成本的商家醒醒吧,程序员不必担心失业,发展空间依旧很大

目录 1 2 3 “AI人”并不算是新鲜事&#xff0c;随着AI的发展&#xff0c;AI主播也开始悄悄进入到直播间中。 持续无间断的直播、比人工费便宜等优势&#xff0c;让很多商家选择了AI主播。 AI主播到底好不好用&#xff1f;终于在今年“双11”现出了原形。 1 AI主播没火过半年…

Python常用插件之emoji表情插件的用法

目录 一、概述 二、安装 三、基本用法 四、高级用法 1、自定义emoji表情 2、使用表情符号列表 3、结合使用Emoji和输入文本 4、动态添加emoji表情 5、自定义Emoji的样式 总结 一、概述 在Python中&#xff0c;使用emoji表情已经成为了一种非常流行的趋势。许多开发者…

Linux Centos 根目录扩展分区(保级教程)

Centos 根目录扩展分区 1. 扩展背景2.列出磁盘信息3. 对磁盘进行分区4. 重启Linux5. 将PV加入卷组centos并分区6.查看分区结果 1. 扩展背景 虚拟机初始分配20G内存&#xff0c;扩容到80G。 2.列出磁盘信息 可以得知容量信息以及即将创建的PV路径&#xff08;通常为“/dev/s…

tcpdump抓包的字节数量与ethtool统计数据不同的原因

情况介绍 在进行RDMA抓包流量分析时&#xff0c;我使用ethtool工具统计了RDMA网卡的流量发送数据数量&#xff0c;然后使用tcpdump进行抓包。 经过分析发现&#xff0c;tcpdump得到的数据数量总是大于ethtool得到的数据数量&#xff0c;而且每个数据包会多出4个字节。 分析 …

代码随想录算法训练营|五十一天

最长递增子序列 300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; 递推公式&#xff1a; 有点像双指针的操作&#xff0c;例如{2,5,6,4,3}&#xff08;写不出来&#xff0c;画图&#xff09; public class Solution {public int LengthOfLIS(int[] nums) {if (n…

如何计算掩膜图中多个封闭图形的面积

import cv2def calMaskArea(image,idx):mask cv2.inRange(image, idx, idx)contours, hierarchy cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)for contour in contours:area cv2.contourArea(contour)print("图形的面积为", area) image是…

Git的GUI图形化工具ssh协议IDEA集成Git

一、GIT的GUI图形化工具 1、介绍 Git自带的GUI工具&#xff0c;主界面中各个按钮的意思基本与界面文字一致&#xff0c;与git的命令差别不大。在了解自己所做的操作情况下&#xff0c;各个功能点开看下就知道是怎么操作的。即使不了解&#xff0c;只要不做push操作&#xff0c…

【Python基础篇】字面量

博主&#xff1a;&#x1f44d;不许代码码上红 欢迎&#xff1a;&#x1f40b;点赞、收藏、关注、评论。 格言&#xff1a; 大鹏一日同风起&#xff0c;扶摇直上九万里。 文章目录 一 Python中字面量的定义二 常见的字面量类型1 数字(Number)2 字符串(String)3 列表(List)4 元…

大模型深入发展,数字化基础设施走向“算粒+电粒”,双粒协同

AI大模型爆发&#xff0c;千行百业期待用生成式人工智能挖掘创新应用与提升生产力。不过&#xff0c;高效的大模型应用底层实际需要更灵活、多元的算力去支撑。在这个重要的技术窗口下&#xff0c;11月10日&#xff0c;由中国智能计算产业联盟与ACM中国高性能计算专家委员会共同…

十月份 NFT 市场显示复苏迹象,等待进一步的积极发展

作者: stellafootprint.network 10 月份&#xff0c;比特币价格大幅飙升&#xff0c;NFT 市场出现了复苏迹象&#xff0c;月度交易量和用户数均增长了 15.2%。尽管 10 月份的数据相比 9 月份有所改善&#xff0c;但仍然不及 8 月份和之前几个月的水平。因此&#xff0c;现在断…

一、认识微服务

目录 一、单体架构 二、分布式架构 三、微服务 1、微服务架构特征&#xff1a; 1.单一职责&#xff1a; 2.面向服务&#xff1a; 3.自治&#xff1a; 4.隔离性强&#xff1a; 2、微服务结构&#xff1a; 3、微服务技术对比&#xff1a; 一、单体架构 二、分布式架构 三…