/*
* tree[x].left   表示以 x 为节点的左儿子
* tree[x].right  表示以 x 为节点的右儿子
* tree[x].size   表示以 x 为根的节点的个数(大小)
*/

struct SBT
{
    int key,left,right,size;
} tree[10010];
int root = 0,top = 0;

void left_rot(int &x)         // 左旋
{
    int y = tree[x].right;
    if (!y)	return;
    tree[x].right = tree[y].left;
    tree[y].left = x;
    tree[y].size = tree[x].size;
    tree[x].size = tree[tree[x].left].size + tree[tree[x].right].size + 1;
    x = y;
}

void right_rot(int &x)        //右旋
{
    int y = tree[x].left;
    if (!y)	return;
    tree[x].left = tree[y].right;
    tree[y].right = x;
    tree[y].size = tree[x].size;
    tree[x].size = tree[tree[x].left].size + tree[tree[x].right].size + 1;
    x = y;
}

void maintain(int &x,bool flag)  //维护SBT状态
{
    if (!x)	return;
    if (flag == false)           //左边
    {
        if(tree[tree[tree[x].left].left].size > tree[tree[x].right].size)//左孩子的左孩子大于右孩子
            right_rot(x);
        else if (tree[tree[tree[x].left].right].size > tree[tree[x].right].size) //左孩子的右孩子大于右孩子
        {
            left_rot(tree[x].left);
            right_rot(x);
        }
        else
            return;
    }
    else                       //右边
    {
        if(tree[tree[tree[x].right].right].size > tree[tree[x].left].size)//右孩子的右孩子大于左孩子
            left_rot(x);
        else if(tree[tree[tree[x].right].left].size > tree[tree[x].left].size) //右孩子的左孩子大于左孩子
        {
            right_rot(tree[x].right);
            left_rot(x);
        }
        else
            return;
    }
    maintain(tree[x].left,false);
    maintain(tree[x].right,true);
    maintain(x,true);
    maintain(x,false);
}

void insert(int &x,int key)  //插入
{
    if (x == 0)
    {
        x = ++top;
        tree[x].left = 0;
        tree[x].right = 0;
        tree[x].size = 1;
        tree[x].key = key;
    }
    else
    {
        tree[x].size++;
        if(key < tree[x].key)
            insert(tree[x].left,key);
        else
            insert(tree[x].right,key);//相同元素可插右子树
        maintain(x,key >= tree[x].key);
    }
}

int remove(int &x,int key)  //利用后继删除
{
    tree[x].size--;
    if(key > tree[x].key)
        remove(tree[x].right,key);
    else  if(key < tree[x].key)
        remove(tree[x].left,key);
    else  if(tree[x].left !=0 && !tree[x].right) //有左子树,无右子树
    {
        int tmp = x;
        x = tree[x].left;
        return tmp;
    }
    else if(!tree[x].left && tree[x].right != 0) //有右子树,无左子树
    {
        int tmp = x;
        x = tree[x].right;
        return tmp;
    }
    else if(!tree[x].left && !tree[x].right)    //无左右子树
    {
        int tmp = x;
        x = 0;
        return tmp;
    }
    else                                      //左右子树都有
    {
        int tmp = tree[x].right;
        while(tree[tmp].left)
            tmp = tree[tmp].left;
        tree[x].key = tree[temp].key;
        remove(tree[x].right,tree[tmp].key);
    }
}

int getmin(int x)    //求最小值
{
    while(tree[x].left)
        x = tree[x].left;
    return tree[x].key;
}

int getmax(int x)    //求最大值
{
    while(tree[x].right)
        x = tree[x].right;
    return tree[x].key;
}

int pred(int &x,int y,int key)   //前驱,y初始前驱,从0开始, 最终要的是返回值的key值
{
    if(x == 0)
        return y;
    if(key > tree[x].key)
        return pred(tree[x].right,x,key);
    else
        return pred(tree[x].left,y,key);
}

int succ(int &x,int y,int key)   //后继,同上
{
    if(x == 0)
        return y;
    if(key < tree[x].key)
        return succ(tree[x].left,x,key);
    else
        return succ(tree[x].right,y,key);
}

int select(int &x,int k)   //查找第k小的数
{
    int r = tree[tree[x].left].size + 1;
    if(r == k)
        return tree[x].key;
    else if(r < k)
        return select(tree[x].right,k - r);
    else
        return select(tree[x].left,k);
}

int rank(int &x,int key)   //key排第几
{
    if(key < tree[x].key)
    {
        return rank(tree[x].left,key);
    }
    else if(key > tree[x].key)
        return rank(tree[x].right,key) + tree[tree[x].left].size + 1;
    else
        return tree[tree[x].left].size + 1;
}

int main()
{
    //insert(root,key);
    //delete(root,key)
    return 0;
}

  

  

详情查看陈启峰大神的论文

Size Balance Tree(SBT模板整理)的更多相关文章

  1. Size Balanced Tree(SBT树)整理

    不想用treap和Splay,那就用SB树把,哈哈,其实它一点也SB,厉害着呢. 先膜拜一下作者陈启峰.Orz 以下内容由我搜集整理得来. 一.BST及其局限性 二叉查找树(Binary Search ...

  2. 初学 Size Balanced Tree(bzoj3224 tyvj1728 普通平衡树)

    SBT(Size Balance Tree), 即一种通过子树大小(size)保持平衡的BST SBT的基本性质是:每个节点的size大小必须大于等于其兄弟的儿子的size大小: 当我们插入或者删除一 ...

  3. Size Balanced Tree

    Size Balanced Tree(SBT)是目前速度最快的平衡二叉搜索树,且能够进行多种搜索操作,区间操作:和AVL.红黑树.伸展树.Treap类似,SBT也是通过对节点的旋转来维持树的平衡,而相 ...

  4. Size Balanced Tree(SBT) 模板

    首先是从二叉搜索树开始,一棵二叉搜索树的定义是: 1.这是一棵二叉树: 2.令x为二叉树中某个结点上表示的值,那么其左子树上所有结点的值都要不大于x,其右子树上所有结点的值都要不小于x. 由二叉搜索树 ...

  5. ACM算法模板整理

    史诗级ACM模板整理 基本语法 字符串函数 istream& getline (char* s, streamsize n ); istream& getline (char* s, ...

  6. C基础 - 终结 Size Balanced Tree

    引言 - 初识 Size Balanced Tree 最近在抽细碎的时间看和学习 random 的 randnet 小型网络库. iamrandom/randnet - https://github. ...

  7. 字符串系列——KMP模板整理

    KMP模板整理 KMP与扩展KMP: /*vs 2017/ vs code以外编译器,去掉windows.h头文件和system("pause");*/ #include<i ...

  8. 子树大小平衡树(Size Balanced Tree,SBT)操作模板及杂谈

    基础知识(包括但不限于:二叉查找树是啥,SBT又是啥反正又不能吃,平衡树怎么旋转,等等)在这里就不(lan)予(de)赘(duo)述(xie)了. 先贴代码(数组模拟): int seed; int ...

  9. Link-Cut Tree指针模板

    模板: 以下为弹飞绵羊代码: #define Troy #include "bits/stdc++.h" using namespace std; ; inline int rea ...

随机推荐

  1. Windows操作系统优化(Win7版) - 进阶者系列 - 学习者系列文章

    Windows系统优化是个永恒的话题.在操作系统的打包制作方面更是有得一拼.前面提到的龙帝国社区的XP系统就是一个典型的例子,打包好的系统就已经是经过优化的,使用者无需再使用优化工具进行处理.下面就对 ...

  2. Linux 平台安装Oracle Database 12c

    1)下载Oracle Database 12cRelease 1安装介质 官方的下载地址: 1:http://www.oracle.com/technetwork/database/enterpris ...

  3. ORA-04091: table xxxx is mutating, trigger/function may not see it

    今天同事让我看一个触发器为什么老是报错,当执行DML语句触发触发器后,会报ORA-04091错误:ORA-04091: table xxxx is mutating, trigger/function ...

  4. 用tpcc测试对比 innodb 和 tokudb

    测试环境 1台IBM Intel(R) Xeon(R) CPU           E5606  @ 2.13GHz,内存12G cd tpcc/tpcc-mysql/src # make cc lo ...

  5. PHP函数整理(二)

    以下均参考自 php.net 1.curl_setopt_array() 此函数为CURL传输会话批量设置选项.这个函数对于需要设置大量的curl选项是非常有用的,不需要重复的调用curl_setop ...

  6. logback配置详解2<appender>

    logback 常用配置详解(二) <appender> <appender>: <appender>是<configuration>的子节点,是负责写 ...

  7. NOIP2012 普及组 T3 摆花——S.B.S.

    题目描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆.通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号.为了在门口展出更多种花,规定第i种花不能超过ai盆,摆花时 ...

  8. 【读书笔记《Bootstrap 实战》】6.单页营销网站

    我们已经掌握了很多实用 Bootstrap  的重要技能.现在,是时候拿出更多的创意来帮助客户实现他们全方位在线营销的愿望了.此次将带领大家做一个漂亮的单页高端营销网站. 主要任务如下: □ 一个大型 ...

  9. 洛谷P2412 查单词 [trie树 RMQ]

    题目背景 滚粗了的HansBug在收拾旧英语书,然而他发现了什么奇妙的东西. 题目描述 udp2.T3如果遇到相同的字符串,输出后面的 蒟蒻HansBug在一本英语书里面找到了一个单词表,包含N个单词 ...

  10. NOIP2009最优贸易[spfa变形|tarjan 缩点 DP]

    题目描述 C 国有 n 个大城市和 m 条道路,每条道路连接这 n 个城市中的某两个城市.任意两个 城市之间最多只有一条道路直接相连.这 m 条道路中有一部分为单向通行的道路,一部分 为双向通行的道路 ...