zoukankan      html  css  js  c++  java
  • Size Balance Tree(SBT模板整理)

    /*
    * 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;
    }

    详情查看陈启峰的论文

  • 相关阅读:
    leetcode------Single Number II
    leetcode------Same Tree
    Hadoop2.x版本全分布式详细安装过程!!【原创!非抄袭!】
    Hadoop2.X版本伪分布式安装详细介绍【非抄袭,原创!】
    leetcode------Linked List Cycle II
    [转载]c# winform 获取当前程序运行根目录
    [转载]MongoDB设置访问权限、设置用户
    [转载]C#设置开机启动
    datagridview 右键选中行 并弹出菜单
    [转载]async & await 的前世今生
  • 原文地址:https://www.cnblogs.com/ZhaoxiCheung/p/6023657.html
Copyright © 2011-2022 走看看