堆的话,其实就是一个二叉树,并且是个完全二叉树,所谓完全二叉树就是说
但是二叉树分为国内的完全二叉树和国外的完全二叉树
这篇文章讲得很详细可以看看
(239条消息) 完全二叉树标准(详细图解)_@星城的博客-CSDN博客_完全二叉树
然后我们将题目拿上来
我们将操作堆的操作分为两个操作,一个是up(),一个是down()
down就是和自己的子节点比较如果自己比子节点大的话就下移,比较的方法是和自己处于数组的下标的两倍比较,因为两倍和两倍加一正好是自己的左右子节点
然后这道题的思路就是先将所有的点down一次(最后一层不需要down操作)
for(int i=n/2;i;i--){
down(i);
}
然后看题目题目的意思是将前m个数输出出去,就是让它从堆里面出去,并输出,删除最小值的操作就是:
1.将最后一位的数字放到第一位
2.对第一位数字进行down操作将最小的数字顶到第一位,
3.mysize--,成功删除第一位数字
4.接着将第一位输出
#include <iostream>
#include<algorithm>
using namespace std;
int h[100010],mysize;
void down(int u){
int t=u;
if(mysize >= u * 2 && h[t] > h[u * 2]) t = u * 2;
if(mysize >= (u * 2 + 1) && h[t] > h[u * 2 + 1]) t = u * 2 + 1;
if(t != u){
swap(h[u],h[t]);
down(t);
}
}
int main(){
int n,m;
cin>>n>>m;
mysize=n;
for(int i=1;i<=n;i++){
cin>>h[i];
}
for(int i=n/2;i;i--){
down(i);
}
while(m--){
cout<<h[1]<<" ";
h[1]=h[mysize];
mysize--;
down(1);
}
return 0;
}