蒟蒻的学习笔记——平衡树之FHQ_treap

前言

眼看着联赛将近,周围的大佬们都开始学起了splay等高级数据结构算法,蒟蒻的我只好学一学treap,咦!?竟然有一种treap可以支持区间操作(splay)还那么友好码量适中?!小蒟蒻赶紧来安利一波

  • 简介

    fhq_treap是一位名叫fhq的大佬想出来的(这不废话吗),它是基于treap的基础上加以优化得出的算法(这也是句废话),treap就是二叉搜索树加上堆,它每次进行一次操作(插入或删除等)都要经过左右旋转来维护二叉搜索树的平衡,每次都旋转一次好麻烦有木~,于是乎,为了科技的创新偷懒fhq大佬创作出了这样一个算法,大大减少了代码复杂度,也让fhq_treap可以很轻易的完成区间上的操作!!造福(像我一样懒的)人类呀
好我们来进入正题;
为什么fhq_treap能完成如此多的操作还码量适中呢? 一切都得益于两个神奇的操作 merge 和 split。 顾名思义,一个是将两颗treap树合并为一颗,一个是将一颗treap树分裂成两颗treap树。

1. merge

int merge(int x,int y){
    if(!x || !y) return x+y;//如果有一颗为空,那么只要返回不为空的那一颗就行了
    if(rd[x]<rd[y]){   //treap的做法,比较他们的优先值
        ch[x][1]=merge(ch[x][1],y); 
        up(x);return x; // 将x的右子树与y合并为一颗,那么目前的x就是合并后的树
    }
    else{
        ch[y][0]=merge(x,ch[y][0]);
        up(y);return y;//反之亦然
    }
}

2.split

void split(int now,int k,int &x,int &y){//意思是将now树,以k为分割点(大于k在右边,小于K在左边),分为x,y两棵树
    if(!now) x=y=0;//如果now 树为空,那么x,y树都为空.
    else{
        if(val[now]<=k){
            x=now,split(ch[now][1],k,ch[now][1],y);
        }
        else 
           y=now,split(ch[now][0],k,x,ch[now][0]);
        up(now);
    }
} 

好了,两个基本操作讲完了,那么他有什么用?

以这两个操作为基础,就可以解决其他操作啦~

先看看插入

insert

int insert(int &root,int x){//原树是root,要插入x这个点
    int a,b;
    int v=val[x];
    split(root,v,a,b);
    root=marge(marge(a,x),b);
}

如果看不懂代码可以看看图。

这是一颗treap树,右边为要插入的点。

new1.png

我们先把原树按要插入这个点的值分为两颗树

new2.png

然后再要插入的点和小于他的那颗树连起来

new3.png

最后只需将这颗树与大于他的这颗树连起来就行了

new4.png

insert就讲完了。

继续挖坑以后有时间填

转载于:https://www.cnblogs.com/czj2005/p/9601131.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值