构建大根堆:进行N/2次down()操作
down()操作内容:选两个子节点中最大的跟当前结点比较
1.比当前结点大:与当前结点交换,交换的子节点的子树可能引起变化,需要进行down()操作
2.比当前结点小:无需交换 已经满足条件
堆顶堆尾互换实现堆排序
将堆顶输出,再与堆尾互换,堆的数量减1
交换可能引起了变化,需要对堆顶进行down()操作
#include <iostream>
using namespace std;
const int maxn=1e5+5;
int heap[maxn];
int n,m;
int siz;
void down(int u){
int t=u;
if(u*2<=siz&&heap[t]>heap[u*2]){
t=u*2;
}
if(u*2+1<=siz&&heap[t]>heap[u*2+1]){
t=u*2+1;
}
if(u!=t){
swap(heap[u],heap[t]);
down(t);
}
return ;
}
int main(){
cin>>n>>m;
siz=n;
for(int i=1;i<=n;i++){
cin>>heap[i];
}
for(int i=n/2;i>=1;i--){
down(i);
}
while(m--){
cout<<heap[1]<<" ";
heap[1]=heap[siz];
siz--;
down(1);
}
return 0;
}