【模板】小根堆模板

小根堆的两种写法

手写堆

可以视作是一种完全二叉树结构

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int Maxn=1000005;
int sta[Maxn];
int n,tot=0;//tot记录元素总数,记得及时更新
inline int read() {
    int x=0,w=1;
    char ch=0;
    while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
    if(ch=='-') w=-1,ch=getchar();
    while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*w;
}
inline void push(int b) {
    sta[++tot]=b;
    for(int i=tot,j=i>>1; j; i=j,j=i>>1) {
        if(sta[j]>sta[i]) swap(sta[j],sta[i]);
        //只需要判断当前节点与父亲的大小关系
    }
}
inline void pop() {
    sta[1]=sta[tot--];//最小值覆盖掉
    for(int i=1,j=i<<1; j<=tot; i=j,j=i<<1) {
        if(j+1<=tot&&sta[j+1]<sta[j]) j++;//因为是小根堆,所以在两个兄弟节点之间选取更小的那个向上推
        if(sta[i]<sta[j]) break;//此时没有交换的必要
        else swap(sta[i],sta[j]);

    }
}
int main() {
    n=read();
    int a,b;
    for(int i=1; i<=n; i++) {
        a=read();
        if(a==1) {
            b=read();
            push(b);
        } else if(a==2) printf("%d\n",sta[1]);
        else if(a==3) pop();
    }
    return 0;
}

STL

可以用优先队列

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
priority_queue <int> q;//定义堆
int n;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int opt,x;
        scanf("%d",&opt);
        if(opt==1) scanf("%d",&x),q.push(-x);//加负号
        if(opt==2) printf("%d\n",-q.top());//加负号
        if(opt==3) q.pop();
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/bbqub/p/11900315.html