把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

【模板】堆

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

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

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

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

堆有两种基本的写法

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;
}
posted @ 2019-03-15 13:26  Kan_kiz  阅读(192)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end