数据结构——堆排序

Posted flydoggie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构——堆排序相关的知识,希望对你有一定的参考价值。

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

 

以上是关于数据结构——堆排序的主要内容,如果未能解决你的问题,请参考以下文章

14.VisualVM使用详解15.VisualVM堆查看器使用的内存不足19.class文件--文件结构--魔数20.文件结构--常量池21.文件结构访问标志(2个字节)22.类加载机制概(代码片段

一文带你了解堆排序

堆排序代码

堆排序-代码版

[ 数据结构 -- 手撕排序算法第七篇 ] 堆及其堆排序

106,排序-堆排序