838. 堆排序
Posted 幽殇默
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了838. 堆排序相关的知识,希望对你有一定的参考价值。
https://www.acwing.com/problem/content/840/
在进行down操作的时候,只需要让根节点和它的左右儿子结点比较就可以了。
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=1e5+10;
int a[N],cnt;
void down(int u)
{
int t=u;
if(u*2<=cnt&&a[u*2]<a[t]) t=u*2;//左儿子存在且小于根
if(u*2+1<=cnt&&a[u*2+1]<a[t]) t=u*2+1;//右儿子
if(u!=t)
{
swap(a[u],a[t]);
down(t);
}
}
int main(void)
{
int n,m; cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
cnt=n;
for(int i=n/2;i>=1;i--) down(i);// 从n/2 开始是因为最下面一层没有儿子,故不需要down
//也可以理解为将所有的根节点down 因为 左 u*2 右 u*2+1 其根都是u 即 n/2
while(m--)
{
cout<<a[1]<<" ";
a[1]=a[cnt--];
down(1);
}
return 0;
}
以上是关于838. 堆排序的主要内容,如果未能解决你的问题,请参考以下文章