AcWing 838. 堆排序
. 堆排序
一、题目描述
输入一个长度为 的整数数列,从小到大输出前 小的数。
输入格式
第一行包含整数 和 。
第二行包含 个整数,表示整数数列。
输出格式
共一行,包含 个整数,表示整数数列中前 小的数。
数据范围
,
输入样例:
5 3
4 5 1 3 2
输出样例:
1 2 3
二、堆的数据结构
堆是一个完全二叉树:除了最后一层结点以外,上面的每一层都是满的。最后一层的结点是从左到右排布的。
小根堆:每一个点都是小于左右儿子的,所以根节点就是树中最小值.或者叫小顶堆。(递归定义)
存储方式:全新的存储方式,用一维数组来存。因为是完全二叉树,所有数据的下标是有规则可以找到的。
位置, 左儿子 , 右儿子
下标是从开始的,从开始不方便,因为还是自己没法玩。
三、堆操作的基本方法
- 往下调整
比如现在堆已经维护好了,我们要把头结点的值
1
3 4
3 5 4 5
假设把头结点值换一下,换成6,
6
3 4
3 5 4 5
现在就不是一个小顶堆了,因为不比小啊,所以需要对进行调整,向下移动。
在中找到一个最小值,然后交换 (操作时,如果当前结点大于左右儿子,与左右儿子中小的进行交换)
3
6 4
3 5 4 5
然后继续在中找最小值,继续交换
3
3 4
6 5 4 5
,移动完毕!
- 往上调整
比如现在堆已经维护好了,我们把修改为
3
3 4
3 5 4 2
就需要找出 ,交换 (与父结点对比,如果比父结点小,则交换自己与父结点)
3
3 2
3 5 4 4
继续查询,发现在,继续交换
2
3 3
3 5 4 4
不再交换,,移动完毕。
四、手写一个堆(小根堆)
1、插入一个数
heap[++sz]=x; //在一维数组最后一个位置填充x
up(sz); //将最后一个元素不断上移
2、求最小值
heap[1]
3、删除最小值
heap[1]=heap[sz--]; //就是把尾部最后一个元素替换掉头元素,然后sz--
down(1); //然后再down(1)就行了
4、删除任意一个元素
heap[k]=heap[sz--];
down(k);
up(k); //其实只能执行一个,因为大了向下走。小了向上走嘛
5、修改任意一个元素
heap[k]=x;
down(k);
up(k);
两个基本操作,这两个操作结合起来就能完成上面五个操作。
---> 向下调整
---> 向上调整
五、如何高效创建堆
六、完整代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m;
int sz;
int heap[N];
void down(int u) {
int t = u;
if (u * 2 <= sz && heap[u * 2] < heap[t])t = u * 2;
if (u * 2 + 1 <= sz && heap[u * 2 + 1] < heap[t])t = u * 2 + 1;
if (u != t) {
swap(heap[u], heap[t]);
down(t);
}
}
void up(int u) {
while (u / 2 && heap[u / 2] > heap[u]) {
swap(heap[u / 2], heap[u]);
u /= 2;
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> heap[i];
sz = n;
for (int i = n / 2; i >= 1; i--) down(i);
while (m--) {
printf("%d ", heap[1]);
heap[1] = heap[sz--];
down(1);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2017-09-15 Centos查找大文件的办法