模板 SBT

本文详细介绍了傻逼树(SBT)的数据结构及其核心操作,包括插入、删除、查找等,并提供了完整的C++实现代码。SBT是一种自平衡的二叉搜索树,能够高效地进行元素的增删查操作。

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

傻逼树模板

struct SBT{

    const static int maxn = 1e5 + 15;

    int lft[maxn] , rht[maxn] , key[maxn] , s[maxn] , tot , root ;

    void init(){ tot = root = 0 ; }

    void init( int x , int val = 0 ){
        lft[x] = rht[x] = 0 , key[x] = val , s[x] = 1;
    }

    inline void up(int x){
        s[x] = s[lft[x]] + s[rht[x]] + 1;
    }

    void lr(int &t){
        int k = rht[t];
        rht[t] = lft[k];
        lft[k] = t;
        s[k] = s[t];
        up(t);
        t = k;
    }

    void rr(int &t){
        int k = lft[t];
        lft[t] = rht[k];
        rht[k]= t;
        s[k] = s[t];
        up(t);
        t = k;
    }

    void Maintain(int &t,bool dir){
        if(dir == false){
            if(s[lft[lft[t]]] > s[rht[t]])
                rr(t);
            else if(s[rht[lft[t]]] > s[rht[t]]){
                lr(lft[t]);
                rr(t);
            }
            else return;
        }
        else{
            if(s[rht[rht[t]]] > s[lft[t]]) lr(t);
            else if(s[lft[rht[t]]] > s[lft[t]]){
                rr(rht[t]);
                lr(t);
            }
            else return;
        }
        Maintain(lft[t],false);
        Maintain(rht[t],true);
        Maintain(t,true);
        Maintain(t,false);
    }
    

    void Insert( int & t , int val ){
        if( t == 0 ){
            t = ++ tot;
            init( t , val );
        }else{
            ++ s[t];
            if( val < key[t] ) Insert( lft[t] , val );
            else Insert( rht[t] , val );
            Maintain( t , val >= key[t] );
        }
    }

    // 删除操作必须保证元素存在
    int Delete(int &t , int v){
        int ret = 0;
        s[t] --;
        if((v == key[t]) || (v<key[t] && lft[t]  == 0) ||(v > key[t] && rht[t] == 0) ){
            ret = key[t];
            if(lft[t] == 0 || rht[t] == 0) t = lft[t] + rht[t];
            else key[t]  = Delete(lft[t],key[t] + 1);
        }
        else{
            if(v < key[t]) ret = Delete(lft[t] , v);
            else ret = Delete(rht[t] , v);
        }
        return ret;
    }

    bool find( int t , int val ){
        if( t == 0 ) return false;
        else if( key[t] == val ) return true;
        else if( val < key[t] ) return find( lft[t] , val );
        else return find( rht[t] , val );
    }


    void preorder( int x ){
        if( lft[x] ) preorder( lft[x] );
        printf("%d " , key[x]);
        if( rht[x] ) preorder( rht[x] );
    }

    int size(){
        return s[root];
    }
    // 查第 k 小 , 必须保证合法
    int kth( int x , int k ){
        if( k == s[lft[x]] + 1 ) return key[x];
        else if( k <= s[lft[x]] ) return kth( lft[x] , k );
        else return kth( rht[x] , k - s[lft[x]] - 1 );
    } 

    //找前驱
    int pred( int t , int v ){
        if( t == 0 ) return v;
        else{
            if( v <= key[t] ) return pred( lft[t] , v );
            else{
                int ans =  pred( rht[t] , v );
                if( ans == v ) ans = key[t];
                return ans;
            }
        }
    }

    // 严格小于 v 的有多少个
    int less( int t , int v ){
        if( t == 0 ) return 0;
        if( v <= key[t] ) return less( lft[t] , v );
        else return s[lft[t]] + 1 + less( rht[t] , v );
    }

    //找后继
    int succ( int t , int v ){
        if( t == 0 ) return v;
        else{
            if( v >= key[t] ) return succ( rht[t] , v );
            else{
                int ans =  succ( lft[t] , v );
                if( ans == v ) ans = key[t];
                return ans;
            }
        }
    }

}sbt;

转载于:https://www.cnblogs.com/qscqesze/p/5582666.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值