如何手写一个堆

堆的基本操作有
1.插入一个数
2.求集合当中的最小值
3.删除最小值
stl写的堆是可以实现上述三个操作

手写的堆还能实现的功能有
4.删除任意一个元素
5.修改任意一个元素

堆是一个完全二叉树。存储可以用一维数组来存储,x的左儿子是2x,右儿子是2x + 1;根节点是1;

两个基本操作是up:往上调整
down:往下调整

堆的基本操作实际上都可以用这两个操作来合成。

稍微复杂一点的是删除最小值(小顶堆),要将小顶堆中的最后一个元素先覆盖到堆顶,之后删除最后一个元素,然后再down操作
在这里插入图片描述
题目:
在这里插入图片描述
实现代码:

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 100010;
int n, m;
int h[N], sizee;

void down(int u){
    
    
    int t = u;
    if(u * 2 <= sizee && h[u * 2] < h[t]) t = u * 2;
    if(u * 2 + 1 <= sizee && h[u * 2 + 1] < h[t]) t = u * 2 + 1;
    if(t != u) swap(h[t], h[u]), down(t);
    
}
int main(){
    
    
    cin >> n >> m;
    sizee = n;
    for(int i = 1; i <= n; i++) cin >> h[i];
    
    for(int i = n / 2; i; i--) down(i);
    
    while(m --){
    
    
        printf("%d ", h[1]);
        
        h[1] = h[sizee];
        sizee --;
        down(1);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44879626/article/details/108047683