堆(Heap)

堆是一棵完全树,堆中某个节点的值总是不大于或不小于其父节点的值。——洛谷试炼场
C++STL里面有个东西叫priority_queue,其实,这就是一个堆
正如洛谷所说,堆是一个完全树,分为两类:
大根堆:
在这里插入图片描述
小根堆:
在这里插入图片描述

堆的实现方法

主要有这样几个操作:push,top,pop (为了和STL统一)
其实如果打模板题的话直接调用priority_queue就可以了
push(插入)
以小根堆为例,我们先把要插进来的值放在堆最下面,然后一步一步的向上比较,如果这个值比他父亲节点的值要小,那么把他们交换一下,一直到这个点已经是根节点或者是它没有比他父亲节点值小,就停止

    inline void push(int val){
        heap[++siz]=val;
        int now=siz;
        while(now>1){
            int rt=now/2;
            if(heap[rt]>heap[now])swap(heap[rt],heap[now]);
            else break;
            now=rt;
        }
    }

pop(弹出)
主要操作是将队头元素和队尾元素交换一下,然后一步一步向下比较,如果这个点比左儿子大,就交换(右儿子同理),直到不能再交换了为止

    inline void pop(){
        heap[1]=heap[siz];
        int rt=1;
        while(rt*2<siz){
            int lson=rt*2;
            int rson=lson+1;
            if(rson>=siz||heap[lson]<heap[rson]){
                if(heap[rt]>heap[lson]){
                    swap(heap[rt],heap[lson]);
                    rt=lson;
                }
                else break;
            }
            else{
                if(heap[rt]>heap[rson]){
                    swap(heap[rt],heap[rson]);
                    rt=rson;
                }
                else break;
            }
        }
        siz--;
    }

top(询问根元素)
这个我觉得没什么好说的,我们heap[1]就一直存的是根啊,直接返回就可以了

    inline int top(){
        return heap[1];
    }

这样到这里我们就把C++STL中的priority_queue中几个常用函数push(val),pop(),top()讲完了,但是,接下来为大家隆重推出一个C++STL两个无法实现的操作:
size(访问堆大小)

    inline int size(){
        return siz;
    }

depth(堆的深度)

    inline int depth(){
		return log(2,siz)+1;
	}

最后是整个堆模板(为了贴近优先队列我是写在了结构体里)
my_priority_queue

struct Priority_queue{
    int heap[N];
    int siz;
    Priority_queue(){
        memset(heap,0,sizeof(heap));
        siz=0;
    }
    inline void push(int val){
        heap[++siz]=val;
        int now=siz;
        while(now>1){
            int rt=now/2;
            if(heap[rt]>heap[now])swap(heap[rt],heap[now]);
            else break;
            now=rt;
        }
    }
    inline void pop(){
        heap[1]=heap[siz];
        int rt=1;
        while(rt*2<siz){
            int lson=rt*2;
            int rson=lson+1;
            if(rson>=siz||heap[lson]<heap[rson]){
                if(heap[rt]>heap[lson]){
                    swap(heap[rt],heap[lson]);
                    rt=lson;
                }
                else break;
            }
            else{
                if(heap[rt]>heap[rson]){
                    swap(heap[rt],heap[rson]);
                    rt=rson;
                }
                else break;
            }
        }
        siz--;
    }
    inline int top(){
        return heap[1];
    }
    inline int size(){
        return siz;
    }
    inline int depth(){
		return log(2,siz)+1;
	}
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值