#include<bits/stdc++.h>
using namespace std;
int N,K;
struct Heap
{
#define dad(x) x/2//父节点
#define le(x) x*2//左儿子
#define ri(x) x*2+1//右儿子
int tot=0,w[1000005];
void xf_up(int x){//向上维护
if(x==1) return ;//如果到达根
if(w[dad(x)]>w[x]) swap(w[dad(x)],w[x]),xf_up(dad(x));//如果还需维护
return ;
}
void xf_down(int x){//向下维护
if(w[le(x)]==0&&w[ri(x)]==0) return ;//如果没有儿子了,即成为叶子节点了,不进行操作
int hh;
if((w[le(x)]<=w[ri(x)]&&w[le(x)!=0])||w[ri(x)]==0) hh=le(x);//注意判断只有一个儿子的情况,将其赋值给hh
else hh=ri(x);
if(w[x]>w[hh]) swap(w[x],w[hh]),xf_down(hh);//需要维护
return ;
}
void push(int x){//push操作
w[++tot]=x;//加入元素
xf_up(tot);//维护
return ;
}
int top(){//top操作
return w[1];
}
void pop(){//pop操作
swap(w[1],w[tot]);//交换最后一个点和根
w[tot--]=0;//将其清除
xf_down(1);//向下维护
return ;
}
bool empty(){//empty操作
if(tot==0) return true;
return false;
}
int size(){//size操作
return tot;
}
};
Heap q;//该结构体就是整个小根堆数据结构
int main()
{
scanf("%d%d",&N,&K);int a;
for(int i=1;i<=N;++i){
scanf("%d",&a);
if(q.size()<K){
q.push(a);
}
else{
if(q.top()<a){
q.pop();//弹出堆顶元素
q.push(a);//压入元素a
}
}
}
while(!q.empty()){//判空
printf("%d ",q.top());
q.pop();
}
return 0;
}
用小根堆解决top-K问题
最新推荐文章于 2024-05-02 09:54:43 发布