当前位置:网站首页>acwing 838. 堆排序 (手写一个堆)
acwing 838. 堆排序 (手写一个堆)
2022-06-22 01:16:00 【_刘小雨】
如何手写一个堆?
- 插入一个数
- 求集合中最小值
- 删除最小值
- 删除任意一个元素
- 修改任意一个元素
[注]: 后面两个是stl 无法直接实现的, stl 的堆就是优先队列
堆
堆是一个完全二叉树(最后一层节点是左右依次排布的)
小根堆为例
每一个节点都小于等于父节点, 根节点就是最小值。
实现:
- 一维数组实现


- 有两个操作
down(x) 、up(x)
顾名思义: 把节点往上移或者往下移动
down(x) : 如果把一个点的值变大了,就需要向下移动;跟叶子节点比较
up(x) : 如果把一个点的值变小了,就需要向上移动;跟父节点比较
如何通过这两个操作实现前面的5个因素呢 heap 表示堆,size表示大小
- heap[++size] = x; up(size);
- heap[1]
- heap[1] = heap[size]; size --; down(1); // 最小值不好直接删除,需要用最后一个值覆盖,然后调整堆
- heap[k] = heap[size]; size --; down(k); up(k); // 只会执行1个操作
- heap[k] = x; down(k), up(k);
题目
输入一个长度为 n 的整数数列,从小到大输出前 m 小的数。
输入格式
第一行包含整数 n 和 m。
第二行包含 n 个整数,表示整数数列。
输出格式
共一行,包含 m 个整数,表示整数数列中前 m 小的数。
数据范围
1≤m≤n≤105,
1≤数列中元素≤109
输入样例:
5 3
4 5 1 3 2
输出样例:
1 2 3
思路:
只涉及排序,分析一下就用到了操作中的2、3 只涉及到down 操作
code:
#include <iostream>
using namespace std;
const int N = 100010;
int n,m;
int h[N], cnt;
void down(int u)
{
// 核心操作就是看根节点、左儿子、右儿子,哪个是最小值
int t = u; // 用t保存 最小的数字
if(u * 2 <= cnt && h[u * 2] < h[t]) t = u * 2; // 保证左儿子存在, 并且左儿子小于父亲
if(u *2 + 1<= cnt && h[u * 2 + 1] < h[t] ) t = u * 2 + 1; // 保证右儿子存在, 并且右儿子小于当前的小的点
if(u != t)
{
swap(h[t], h[u]); // 交换使得最小值在上面
down(t); // 递归处理
}
}
void up(int u)
{
while(u / 2 && h[u / 2] > h[u]) // 如果存在父节点且父节点大
{
swap(h[u / 2], h[u]); // 交换
u /= 2; // 递归处理
}
}
int main()
{
cin >> n >> m;
for(int i = 1; i<=n; i++) cin >> h[i];
cnt = n;
// 初始化堆,从n / 2开始, 能使时间复杂度为O(n), 直接从n开始就会是O(logn)
for(int i = n/2; i; i--) down(i);
while(m--) // 取出前m个小的数字
{
cout << h[1] << ' '; // 取出小根堆的最小数字
h[1] = h[cnt]; // 将堆底元素(最后一个)放在第一位置
cnt --; // 总的个数 - 1
down(1); // 向下调整堆,维护使得最上面元素是最小的元素
}
return 0;
}
边栏推荐
- Rational rose 安装教程
- Amazon evaluation browser, core knowledge points of Amazon evaluation risk control
- Classes and objects (Part 2)
- High score schemes have been opened to the public, and the second round of the China "software Cup" remote sensing competition is coming!
- php-admin部署-解决全部错误
- 产业互联网时代,并不存在真正意义上的中心
- linxu 将文件夹的权限修改为所有人可以访问 777
- [number theory] leetcode1010 Pairs of Songs With Total Durations Divisible by 60
- 英特尔笔试题小整理DIY
- 【第 10 章 基于不变矩的某网站数字验证码识别MATLAB深度学习实战应用案例】
猜你喜欢

测试apk-异常管控Sensor攻击者开发

数学知识复习:三重积分

Brief introduction to jpom: simple and light low intrusive online construction, automatic deployment, daily operation and maintenance, and project monitoring software

测试apk-异常管控WiFi Scan攻击者开发

Function test - Introduction to MySQL database

Expenditure budget and adjustment records and use records output use progress construction process records

同济、阿里获CVPR最佳学生论文,李飞飞获黄煦涛奖,近6000人线下参会

经费预算与调整记录与使用记录输出使用进度搭建过程记录

Classes and objects (Part 2)

ASEMI快恢复二极管FR107参数,FR107实物,FR107应用
随机推荐
Processing of the scenario of more or less delivery by suppliers in SAP mm import purchase business
数学知识复习:三重积分
Commission contract on BSV
I just learned a cool 3D pyramid stereoscopic effect. Come and have a look
Jpom 简介: 简而轻的低侵入式在线构建、自动部署、日常运维、项目监控软件
【第 17 章 基于 Harris 的角点特征检测--Matlab机器学习项目实战】
高分方案纷纷开源,中国“软件杯”遥感赛项第二轮预选赛来了!
将列表分箱,并通过Pyechart绘制柱状图
The way to build the efficiency platform of didi project
第 08 章 基于知识库的手写体数字识别MATLAB深度学习应用实战
一条短视频成本几十万元,虚拟数字人凭“实力”出圈
测试用例设计方法——因果图法
Classes and objects (Part 2)
“早安、午安、晚安” Game Jam
[AMD Comprehensive Search Experience Sharing 618]
出现UnicodeDecodeError: ‘ascii‘ codec can‘t decode byte 0xe9 in position 0: ordinal not in range解决方法
LeetCode 5242. Best English letters with both upper and lower case
依靠可信AI的鲁棒性有效识别深度伪造,帮助银行对抗身份欺诈
华为云发布桌面IDE-CodeArts
2022年Q1手机银行用户规模达6.5亿,加强ESG个人金融产品创新