堆排序算法就是通过维护一个小根堆或者大根堆的数据结构。小/大根堆本质上是一个完全二叉树。利用了完全二叉树的性质,即完全二叉树节点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