AcWing 838. 堆排序(siftDown(int x)递归版本和迭代版本)
原题链接
简单
作者:
minux
,
2020-04-23 23:57:24
,
所有人可见
,
阅读 533
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n, m, sz;
int a[N];
// 小顶堆
// 将堆中的第k位置进行向下调整
// 递归实现
void siftDown(int k){
int i=k;
if(2*k<=sz && a[2*k]<a[i]) i=2*k;
if(2*k+1<=sz && a[2*k+1]<a[i]) i=2*k+1;
if(i!=k){
swap(a[k], a[i]);
siftDown(i);
}
}
// 堆中第k位置向下调整
// 迭代实现
void siftDown2(int k){
while(2*k<=sz){
int j=2*k;
if(j+1<=sz && a[j+1]<a[j])
j++;
if(a[k]<a[j])
break;
swap(a[k], a[j]);
k=j;
}
}
// 堆中第k位置向上调整
void siftUp(int k){
while(k/2 && a[k/2]>a[k]){
swap(a[k/2], a[k]);
k/=2;
}
}
int main(){
// cin.tie(0);
// ios::sync_with_stdio(false);
memset(a, 0x00, sizeof a);
cin>>n>>m;
sz=n;
for(int i=1; i<=n; ++i) cin>>a[i];
for(int i=n/2; i>=1; --i) siftDown2(i);
while(m--){
// 输出堆顶元素
cout<<a[1]<<" ";
a[1]=a[sz];
sz--;
siftDown2(1);
}
return 0;
}