首页 > 其他分享 >SBT模版(Size Balanced Tree)

SBT模版(Size Balanced Tree)

时间:2023-05-31 19:02:43浏览次数:38  
标签:return SBT lefts int rights Tree key Balanced size


关于SBT的介绍及学习,请戳这里。

 

SBT模版:

/*************************************************
数据结构:
SBT(Size Balanced Tree),又称傻逼树;

数据域:
值域key,左孩子left,右孩子right,保持平衡的size;

性质:
每棵子树的大小不小于其兄弟的子树大小;

插入:
插入算法先简单插入节点,然后调用一个维护过程以保持性质;

删除:
删除操作与普通维护size域的二叉查找树相同;

最大值和最小值:
由于SBT本身已经维护了size域;
所以只需用Select(T,1)来求最大值;
Select(T,T.size)求最小值;
其中Select(T,k)函数返回树T在第k位置上的节点值;
**************************************************/
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<climits>
#include<algorithm>
using namespace std;

const int N = 100000;
int key[N], lefts[N], rights[N], size[N];
int u;//根结点
int node;

inline void Left_Rotate(int &x)
{
    int k = rights[x];
    rights[x] = lefts[k];
    lefts[k] = x;
    size[k] = size[x];
    size[x] = size[lefts[x]] + size[rights[x]] + 1;
    x = k;
}

inline void Right_Rotate(int &y)
{
    int k = lefts[y];
    lefts[y] = rights[k];
    rights[k] = y;
    size[k] = size[y];
    size[y] = size[lefts[y]] + size[rights[y]] + 1;
    y = k;
}

void Maintain(int &u, bool flag)//维护
{
    if(flag == false)
    {
        if(size[lefts[lefts[u]]] > size[rights[u]])
            Right_Rotate(u);
        else
        {
            if(size[rights[lefts[u]]] > size[rights[u]])
            {
                Left_Rotate(lefts[u]);
                Right_Rotate(u);
            }
            else return;
        }
    }
    else
    {
        if(size[rights[rights[u]]] > size[lefts[u]])
            Left_Rotate(u);
        else
        {
            if(size[lefts[rights[u]]] > size[lefts[u]])
            {
                Right_Rotate(rights[u]);
                Left_Rotate(u);
            }
            else return;
        }
    }
    Maintain(lefts[u], false);
    Maintain(rights[u], true);
    Maintain(u, true);
    Maintain(u, false);
}

void Insert(int &u, int v)//插入结点
{
    if(u == 0)
    {
        key[u = ++node] = v;
        size[u] = 1;
    }
    else
    {
        size[u]++;
        if(v < key[u])
            Insert(lefts[u], v);
        else
            Insert(rights[u], v);
        Maintain(u, v >= key[u]);
    }
}

int Delete(int &u, int v)//删除结点
{
    size[u]--;
    if( (v == key[u]) || (v < key[u] && lefts[u] == 0) || (v > key[u] && rights[u] == 0) )
    {
        int r = key[u];
        if(lefts[u] == 0 || rights[u] == 0)
            u = lefts[u] + rights[u];
        else
            key[u] = Delete(lefts[u], key[u] + 1);
        return r;
    }
    else
    {
        if(v < key[u])
            return Delete(lefts[u], v);
        else
            return Delete(rights[u], v);
    }
}

int Search(int x, int k)//查询
{
    if(x == 0 || k == key[x])
        return x;
    if(k < key[x])
        return Search(lefts[x], k);
    else
        return Search(rights[x], k);
}

int Select(int u, int k)//返回树在第k位置上的结点值
{
    int r = size[lefts[u]] + 1;
    if(k == r)
        return key[u];
    else if(k < r)
        return Select(lefts[u], k);
    else
        return Select(rights[u], k - r);
}

int Successor(int u, int k)//查询结点k的后继
{
    if(u == 0)
        return k;
    if(key[u] <= k)
        return Successor(rights[u], k);
    else
    {
        int r = Successor(lefts[u], k);
        if(r == k)
            return key[u];
        else
            return r;
    }
}

int Predecessor(int u, int k)//查询结点k的前驱
{
    if(u == 0)
        return k;
    if(key[u] >= k)
        return Predecessor(lefts[u], k);
    else
    {
        int r = Predecessor(rights[u], k);
        if(r == k)
            return key[u];
        else
            return r;
    }
}

int Rank(int u, int k)//排名(rank),也叫秩,求整棵树中从大到小排序的第k位元素;
{
    if(u==0)
        return 1;
    if(key[u] >= k)
        return Rank(lefts[u], k);
    else
        return size[lefts[u]] + Rank(rights[u], k) + 1;
}

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0; i<n; i++)
    {
        int cmd,x;
        scanf("%d%d",&cmd,&x);
        switch(cmd)
        {
        case 1:
            Insert(u,x);
            break;
        case 2:
            Delete(u,x);
            break;
        case 3:
            printf("%d\n", Search(u,x));
            break;
        case 4:
            printf("%d\n", Rank(u,x));
            break;
        case 5:
            printf("%d\n", Select(u,x));
            break;
        case 6:
            printf("%d\n", Predecessor(u,x));
            break;
        case 7:
            printf("%d\n", Successor(u,x));
            break;
        }
    }
    return 0;
}

 

标签:return,SBT,lefts,int,rights,Tree,key,Balanced,size
From: https://blog.51cto.com/u_16146153/6389002

相关文章

  • mongodb压缩——snappy、zlib块压缩,btree索引前缀压缩
    MongoDB3.0WiredTigerCompressionandPerformanceOneofthemostexcitingdevelopmentsoverthelifetimeofMongoDBmustbetheinclusionoftheWiredTigerstorageengineinMongoDB3.0.Itsverydesignandcorearchitecturearelegionsaheadofthecurr......
  • python berkeley DB操作——打开btree索引文件中的database
    打开BDB中某个索引中的数据库代码: frombsddb3importdbimportbsddb3asbsddbprintdb.DB_VERSION_STRINGmydb=db.DB()mydb.open('your_btree_db_filename','databsename',dbtype=db.DB_BTREE)rec=cur.first()whilerec:#printkeyvaluepri......
  • SimpleAdmin手摸手教学之:基于Ant Design Tree组件实现树形结构数据的异步加载
    一、说明当有一个树形结构的数据有非常多个节点的时候,一次性加载所有节点会显得过于臃肿,可能会对性能造成影响,正好AntDesign的树(Tree)组件支持异步加载,于是我就想把异步加载封装为一个组件,可以减少接口数据返回,点击展开节点,动态加载数据。非常好用!二、前端实现需要接收一些......
  • ERESOLVE unable to resolve dependency tree
    错误描述:报错原因(据查):依赖项中存在无法解决的冲突解决方法:使用如下命令npmi--legacy-peer-deps运行结果:......
  • leetcode 637. Average of Levels in Binary Tree
    Givenanon-emptybinarytree,returntheaveragevalueofthenodesoneachlevelintheformofanarray.Example1:Input:3/\920/\157Output:[3,14.5,11]Explanation:Theaveragevalueofnodesonlevel0is3,onlevel......
  • leetcode 669. Trim a Binary Search Tree
    GivenabinarysearchtreeandthelowestandhighestboundariesasLandR,trimthetreesothatallitselementsliesin[L,R](R>=L).Youmightneedtochangetherootofthetree,sotheresultshouldreturnthenewrootofthetrimmedbinarys......
  • leetcode 617. Merge Two Binary Trees
    Giventwobinarytreesandimaginethatwhenyouputoneofthemtocovertheother,somenodesofthetwotreesareoverlappedwhiletheothersarenot.Youneedtomergethemintoanewbinarytree.Themergeruleisthatiftwonodesoverlap,thensumn......
  • leetcode 257. Binary Tree Paths
    Givenabinarytree,returnallroot-to-leafpaths.Forexample,giventhefollowingbinarytree: 1/\23\5Allroot-to-leafpathsare:["1->2->5","1->3"]#Definitionforabinarytreenode.#classTreeNode(obje......
  • leetcode 671. Second Minimum Node In a Binary Tree
    Givenanon-emptyspecialbinarytreeconsistingofnodeswiththenon-negativevalue,whereeachnodeinthistreehasexactlytwoorzerosub-node.Ifthenodehastwosub-nodes,thenthisnode'svalueisthesmallervalueamongitstwosub-nodes.G......
  • leetcode 107. Binary Tree Level Order Traversal II
    Givenabinarytree,returnthebottom-uplevelordertraversalofitsnodes'values.(ie,fromlefttoright,levelbylevelfromleaftoroot).Forexample:Givenbinarytree[3,9,20,null,null,15,7],3/\920/\157returnits......