Heap——数据结构之堆

简介堆

堆是一种数据结构,是一棵二叉树(尽量地满足完全二叉树的规律)。他有一个特点,就是两个儿子的值均大于或小于父节点。那么这个堆就被称为大顶堆或小顶堆。同一级的元素不比较大小,它可以用到优先队列之中,还有其他很神奇的应用。

操作

I.维护队的性质

其实就是一个步骤:如果它不满足堆的性质,那么就继续维护,否则结束。
1.向上维护
如果节点x与它的父亲x/2的关系不合法,则x与x/2交换。

void up(LL x)
{
    LL p=x;
    while (p>1 && d[p/2]<d[p])swap(d[p],d[p/2]),p/=2;
}

2.向下维护
如果节点x与它的儿子的关系不合法,则比较左儿子和右二子的大小,较大(或较小)的那个和x交换。

void down(LL x)
{
    LL l=x*2,r=x*2+1;
    while (l<=tot && d[x]<=d[l] || (r<=tot) && d[x]<=d[r])
    {
        LL mx=l;
        if (r<=tot && d[r]>d[l]) mx=r;//比较大小
        swap(d[x],d[mx]);x=mx;
        l=x*2,r=x*2+1;
    }
}

II.建立堆

首先我们要将一个数组转化成一个堆。那么我们对于数组中的每一个元素,都要维护堆的性质。

void build()
{
    for(int i=tot/2;i>=1;i--) down(i);
    //其中tot表示这个数组的元素个数。
}

III.删除堆顶的元素

当我们要取最优值的时候,我们要将堆顶的元素删掉,然后最后一个元素到堆顶,维护堆。

void del(LL x)
{
    if (d[tot]<d[x])
    {
        memcpy(d[x],d[tot],sizeof(d[x]));tot--;
        down(x);
    } else
    {
        memcpy(d[x],d[tot],sizeof(d[x]));tot--;
        up(x);
    }
}

PS:删除操作可以应用到优先队列之中

IV.插入操作

向堆中添加一个元素到堆末,然后向上维护堆。

void ins(LL x)
{
    d[++tot]=x;
    up(tot);
}

总结

堆时间复杂度: O(nlogn)
堆多应用于优先队列或者是堆排序。
堆是一个重要的数据结构,在很多题目中容易遇到。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值