堆的基本操作有
1.插入一个数
2.求集合当中的最小值
3.删除最小值
stl写的堆是可以实现上述三个操作
手写的堆还能实现的功能有
4.删除任意一个元素
5.修改任意一个元素
堆是一个完全二叉树。存储可以用一维数组来存储,x的左儿子是2x,右儿子是2x + 1;根节点是1;
两个基本操作是up:往上调整
down:往下调整
堆的基本操作实际上都可以用这两个操作来合成。
稍微复杂一点的是删除最小值(小顶堆),要将小顶堆中的最后一个元素先覆盖到堆顶,之后删除最后一个元素,然后再down操作
题目:
实现代码:
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 100010;
int n, m;
int h[N], sizee;
void down(int u){
int t = u;
if(u * 2 <= sizee && h[u * 2] < h[t]) t = u * 2;
if(u * 2 + 1 <= sizee && h[u * 2 + 1] < h[t]) t = u * 2 + 1;
if(t != u) swap(h[t], h[u]), down(t);
}
int main(){
cin >> n >> m;
sizee = n;
for(int i = 1; i <= n; i++) cin >> h[i];
for(int i = n / 2; i; i--) down(i);
while(m --){
printf("%d ", h[1]);
h[1] = h[sizee];
sizee --;
down(1);
}
return 0;
}