【模板】堆

 堆是一种特殊的完全二叉树。以小根堆为例,这种完全二叉树有一个特点,就是它的父节点都比子节点小。符合这样特点的二叉树,我们也称为最小堆。

 反之,如果所有父节点都比子节点要大,这样的完全二叉树称为大根堆,或最大堆。

 (若是最小堆,则最小的数在堆顶/树根。)


按一般意义来讲,一个堆的父节点的优先级都比子节点高。

堆有两种基本的写法



1.手写堆

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#define leftson (cur<<1)
#define rightson (cur<<1|1)
#define father (cur>>1)
#define int long long
#define MAXN 1000000+10
int n=0,m;
int heap[MAXN];
namespace self
{
    #define int long long
    void swap(int h[],int x,int y)
    {
        int t; t=h[x]; h[x]=h[y]; h[y]=t;
        return;
    }
    using namespace self;
    void siftdown(int h[],int i)
    {
        int t;
        bool flag=0;
        while (i*2<=n && flag==0)
        {
            if (h[i]>h[i*2])
            t=i*2;
            else t=i;
            if (i*2+1<=n)
            {
                if(h[t]>h[i*2+1])
                t=i*2+1;
            }
            if (t!=i)
            {
                swap(heap,t,i);
                i=t;
            }
            else flag=1;
        }
        return;
    }
}
using namespace self;
void down(int cur)
{
    int t;
    bool flag=0;
    while (leftson<=n&&(!flag))
    {
        if (heap[cur]>heap[leftson])
        {
            t=leftson;
        }
        else t=cur;
        if (rightson<=n)
        {
            if (heap[t]<heap[rightson])
            {
                t=rightson;
            }
        }
        if (t!=cur)
        {
            swap(heap,t,cur);
            cur=t;
        }
        else flag=1;
    }
}
void up(int cur)
{
    bool flag=0;
    if (cur==1) return;
    while (cur!=1&&(!flag))
    {
        if (heap[cur]<heap[father])
        {
            swap(heap,cur,father);
        }
        else flag=1;
        cur=father;
    }
    return;
}
signed main()
{
    scanf("%lld",&m);
    int q;
    while (m--)
    {
        scanf("%lld",&q);
        if (q==1)
        {
            n++;
            scanf("%lld",&heap[n]);
            up(n);
            continue;
        }
        if (q==2)
        {
            printf("%lld\n",heap[1]);
            continue;
        }
        if (q==3)
        {
            heap[1]=heap[n];
            n--;
            siftdown(heap,1);
        }
    }
    return 0;
}

无良无分析式玄学代码


2.STL 堆:优先队列


 队列是一种先进先出(FIFO)式的数据结构。优先队列与其不同的地方是,优先队列存储的时候,会将(定义的)优先级较大的元素放在较小的元素之前。也就是说优先级最大的元素放在队头。 那么这里就和堆有了共同点:优先级大的放在队前/堆高层。
大根堆的定义:
queue< int >q;


小根堆的定义:
priority_queue< int,vector< int >,greater< int > >q;


一个优先队列的操作:


qwq

小根堆基本操作代码

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
priority_queue<int,vector<int>,greater<int> >q;
int main()
{
    int n;
    scanf("%d",&n);
    int x;
    while(n--)
    {
        scanf("%d",&x);
        if (x==1)//命令1 在堆中加入一个数
        {
            scanf("%d",&x);
            q.push(x);
            continue;
        }
        if (x==2)//命令2 输出当前序列中最小数
        {
            printf("%d\n",q.top());
            continue;
        }
        if (x==3)//命令3 删除当前序列中最小数
        q.pop();
    }
    return 0;
}

转载于:https://www.cnblogs.com/Kan-kiz/p/10536416.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值