堆排序算法就是通过维护一个小根堆或者大根堆的数据结构。小/大根堆本质上是一个完全二叉树。利用了完全二叉树的性质,即完全二叉树节点x的子节点编号为2x和2x+1。
利用这个性质,我们可以让一个一维数组来模拟这个二叉树,数组下标从1开始建立,下标为2*x和2*x+1的就是x的左子树和右子树。

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
//h[n]是堆数组(一维存储)
int h[N];
//s表示的是堆的大小,就是size
int s;
//向下维护堆(此代码是小根堆)
void down(int x){
int t = x;
//判断x是否小于左右子节点
if( x*2 <= s && h[x*2] < h[t]) t = x*2;
if( x*2+1 <= s && h[x*2+1] < h[t]) t = x*2+1;
//如果x小于了左右子节点,则交换数值
if( t != x){
swap(h[t],h[x]);
//递归维护子节点的子节点
down(t);
}
return ;
}
int main(){
ios::sync_with_stdio(0);
cin.tie();
int n,m;
cin>>n>>m;
for(int i = 1 ; i <= n ; i ++ ){
cin>>h[++s];
}
//建堆(堆的初始化),从 n/2 开始维护整个堆的性质(n/2也就是最后一层的上面那层,从n/2开始维护也可以保证整个堆的性质)
for(int i = s/2 ; i >= 1 ; i -- )
down(i);
while(m--){
cout<<h[1]<<" ";
h[1] = h[s -- ];
down(1);
}
return 0;
}
来源:https://www.cnblogs.com/Flydoggie/p/12283814.html