堆排序(小根堆模板)

news2025/1/9 16:55:22

输入一个长度为 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是节点总数。 

 

 

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

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

相关文章

找工作什么平台最可靠

吉鹿力招聘网是最可靠的找工作平台。可以直接和HR沟通岗位情况&#xff0c;方便快捷。同时&#xff0c;吉鹿力招聘网还有一些其他功能&#xff0c;比如可以找到更精准的人才&#xff0c;以及专业的招聘网站&#xff0c;可以帮助求职者找到合适的职位。吉鹿力招聘网还有一个特点…

项目应用多数据源动态切换(动态切换数据库连接)

文章目录 前言准备阶段具体配置功能展示注解方式切换数据源代码方式切换数据源优化方式 动态添加删除数据源事务问题参考文章 前言 最近公司的权限项目要实现多租户的功能&#xff0c;于是就要做数据隔离以确保每个租户的数据的安全性&#xff0c;但是项目中也要动态的提供能够…

Unity性能优化分析篇

性能优化是游戏项目开发中一个重要环节。游戏帧率过低&#xff0c;手机发烫&#xff0c; 包体太大&#xff0c;低端机上跑不起来等, 这些都需要来做优化&#xff0c;不管过去&#xff0c;现在&#xff0c;未来&#xff0c;性能优化都是永恒的话题。 而性能优化首先要掌握的是性…

对话金山云高级副总裁刘涛 | 做大模型公司的助力者

“ AIGC的应用化阶段将很快到来&#xff1b;AGI&#xff0c;已步入助手阶段。” 口述 | 刘涛 整理 | 梦婕&云舒 出品&#xff5c;极新 在10月的最后一天&#xff0c;极新有幸采访到了金山云高级副总裁刘涛。我们深入探讨了“云计算逐鹿 AIGC”的话题。作为中国公有云互…

Opentracing概念介绍——Span

文章首发公众号&#xff1a;海天二路搬砖工 引言 作为分布式跟踪系统的标准化API&#xff0c;OpenTracing提供了一种通用的方式来追踪和分析分布式系统中的请求和操作。 在Opentracing中&#xff0c;Span是基本的跟踪单元&#xff0c;用于描述在分布式系统中的一个操作或事件…

csdn2023必看系列:最牛最全面的JMeter实现接口自动化测试教程

【文章末尾给大家留下了大量的福利哦】 一、JMETER的环境搭建 参考&#xff1a;https://www.cnblogs.com/qmfsun/p/4902534.html 二、JMETER的汉化 临时汉化方法&#xff1a;打开jmeter&#xff0c;options-->choose language-->选择语言 可以根据自己的需要选择简体…

【Python小程序】浮点矩阵加减法

一、内容简介 本文使用Python编写程序&#xff0c;实现2个m * n矩阵的加、减法。具体过程如下&#xff1a; 给定两个m*n矩阵A和B&#xff0c;返回A与B的和或差。 二、求解方法 将两个矩阵对应位置上的元素相加。 三、Python代码 import numpy as np# 用户输入两个矩阵的维…

Leetcode—67.二进制求和【简单】

2023每日刷题&#xff08;二十八&#xff09; Leetcode—67.二进制求和 实现代码 void reverse(char *a, int len) {for(int i 0; i < len / 2; i) {char tmp a[i];a[i] a[len - 1 - i];a[len - 1 - i] tmp;} }char* addBinary(char* a, char* b) {int len1 strlen(a…

微信小程序:仅前端实现对象数组的模糊查询

效果 核心代码 //对数组进行过滤&#xff0c;返回数组中每一想满足name值包括变量query的 let result array.filter(item > { return item.name.includes(query); }); 完整代码 wxml <input type"text" placeholder"请输入名称" placeholder-styl…

YOLO目标检测——番茄数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;番茄检测数据集说明&#xff1a;番茄目标检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富标签说明&#xff1a;使用lableimg标注软件标注&#xff0c;标注框质量高&#xff0c;含voc(xml)、coco(json)和yolo(txt)三种格式标签…

YashanDB服务端个人版安装部署

介绍 崖山数据库系统YashanDB是深圳计算科学研究院完全自主研发设计的新型数据库系统&#xff0c;融入原创理论&#xff0c;支持单机/主备、共享集群、分布式等多种部署方式&#xff0c;覆盖OLTP/HTAP/OLAP交易和分析混合负载场景&#xff0c;为客户提供一站式的企业级融合数据…

2023年11月最新视频号下载提取工具?

视频号下载提取器教程&#xff1a; 1. 首先&#xff0c;在微信客户端中搜索并添加"下载小助手儿"并关注获取推送的消息。然后添加视频下载助手为好友&#xff0c;可以帮助你解析视频号链接。 2. 打开微信&#xff0c;并找到你想要提取链接的视频号。进入该视频页面后…

YOLO目标检测——红花数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;红花检测数据集可以用于监测和分析红花的生长情况&#xff0c;包括生长速度、叶面积、花朵数量等&#xff0c;为农民提供精确的决策支持&#xff0c;以提高红花产量和品质。数据集说明&#xff1a;红花检测数据集&#xff0c;真实场景的高质量图片数据…

我国陆地遥感卫星发展现状与展望

一、引言 从20世纪90年代末至今&#xff0c;我国陆地遥感卫星事业历经二十多年&#xff0c;实现了从无到有、从小到大、从弱到强的跨越发展。随着高分辨率对地观测系统重大专项&#xff08;高分专项&#xff09;、《陆海观测卫星业务发展规划&#xff08;2011—2020年&#xff…

CountDownLatch使用

常用于多线程场景&#xff0c;待多线程都结束后方可继续主线程逻辑处理 CodeConstant 常量类 import java.util.HashMap; import java.util.Map;public class CodeConstant {public static final Map<String, Map<String, String>> CODE new HashMap<>();…

零基础快速上手STM32开发(手把手保姆级教程)

零基础快速上手STM32开发&#xff08;手把手保姆级教程&#xff09; 1. 前言 作为一名嵌入式工程师&#xff0c;STM32 是必须要学习的一款单片机&#xff0c;同时这款单片机资料足够多&#xff0c;而且比较简单&#xff0c;非常适合初学者入门。 STM32 是一款由 STMicroelec…

酷柚易汛ERP - 商品库存余额表操作指南

1、应用场景 商品库存余额表用于查询商品在各仓库的实际结存量、单位成本以及成本等明细。 2、主要操作 打开【仓库】-【商品库存余额表】&#xff0c;可筛选仓库、商品、商品类别&#xff0c;导出/打印等操作见【销货单】不再赘述。 3、分享操作 库存余额分享&#xff0c;…

win7纯净版没有网卡驱动怎么办(msdn重装的系统)

当电脑重新安装Windows7系统之后&#xff0c;发现无法连接网络的情况&#xff0c;可以找一台能正常上网使用的电脑&#xff0c;打开浏览器软件&#xff0c;搜索“360驱动大师”&#xff0c;下载360驱动大师网卡版到U盘&#xff0c;然后拷贝到自己的win7电脑上安装网卡驱动&…

C++ final

参考:https://blog.csdn.net/qq_45358642/article/details/124232686#t2 不想让类继承 方式一&#xff1a;将类的构造函数设置为私有 子类不能调用父类构造函数初始化来实例化对象&#xff0c;所以不能继承 缺点&#xff1a;我们自己也不能够实例化出对象 class A { privat…

酷柚易汛ERP - 序列号跟踪表

1、应用场景 对于3C数码、医疗器械等行业&#xff0c;商品价值高且需要进行售后服务&#xff0c;需要对商品进行序列号管理&#xff0c;通过序列号跟踪表可查询每个序列号入库、出库、退货、调拨、盘点等流向。 2、主要操作 打开【仓库】-【序列号跟踪表】&#xff08;系统设…