数据结构——堆排序

╄→гoц情女王★ 提交于 2020-02-08 16:44:36

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

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!