左偏树模板

本文详细介绍了左偏树的基本操作实现,包括获取根节点、合并、插入、删除节点等核心功能,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#define null -1
struct Node
{
    int key;
    int l,r,f,dis;
}tree[maxn];
//得到节点标号为r的节点的跟节点编号
int getroot(int r)
{
    if(r==null)return r;
    while(tree[r].f!=null)
        r=tree[r].f;
    return r;
}
//合并两个左偏树
int merge(int rx,int ry)
{
    if(rx==null)return ry;
    if(ry==null)return rx;
    if(tree[rx].key>tree[ry].key)swap(rx,ry);
    int r=merge(tree[rx].r,ry);
    tree[rx].r=r;
    tree[r].f=rx;
    if(tree[rx].l==null||tree[r].dis>tree[tree[rx].l].dis)
        swap(tree[rx].l,tree[rx].r);
    if(tree[rx].r==null)tree[rx].dis=0;
    else tree[rx].dis=tree[tree[rx].r].dis+1;
    return rx;
}
//插入节点,节点编号为r,插入后的节点为root
int insert(int r,int key,int root)
{
    tree[r].key=key;
    tree[r].l=tree[r].r=tree[r].f=null;
    tree[r].dis=0;
    return root=merge(root,r);
}
//删除编号为o的点
int del(int o)
{
    if(o==null)return o;
    int l=tree[o].l;
    int r=tree[o].r;
    int y=tree[o].f;
    int x;
    tree[o].l=tree[o].r=tree[o].f=null;
    tree[x=merge(l,r)].f=y;
    if(y!=null&&tree[y].l==o)tree[y].l==x;
    if(y!=null&&tree[y].r==o)tree[y].r==x;
    for(;y!=null;x=y,y=tree[y].f)
    {
        if(tree[tree[y].l].dis<tree[tree[y].r].dis)
            swap(tree[y].l,tree[y].r);
        if(tree[tree[y].r].dis+1==tree[y].dis)
            break;
        tree[y].dis=tree[tree[y].r].dis+1;
    }
    if(x!=null)return getroot(x);
    else return getroot(y);
}
Node top(int r)
{
    return tree[r];
}
//返回最值
Node pop(int &o)
{
    Node out=tree[o];
    int l=tree[o].l,r=tree[o].r;
    tree[o].l=tree[o].r=tree[o].f=null;
    tree[l].f=tree[r].f=null;
    o=merge(l,r);
    return out;
}
//编号为o的节点加上val
int add(int o,int val)
{
    if(o==null)return o;
    if(tree[o].l==null&&tree[o].r==null&&tree[o].f==null)
    {
        tree[o].key+=val;
        return o;
    }
    int key=tree[o].key+val;
    int rt=del(o);
    return insert(o,key,rt);
}
void init()
{
    for(int i=1;i<=N;i++)
    {
        scanf("%d",tree[i].key);
        tree[i].l=tree[i].r=tree[i].f=null;
        tree[i].dis=0;
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值