zoukankan      html  css  js  c++  java
  • 二叉查找树学习笔记(BST)

    我土了....终于开始看平衡树了,以前因为害怕一直不敢看数据结构...浑浑噩噩跟同学落了1—2个数据结构没看....果然,我是最弱的

    二叉查找树,遵守每个点的左儿子小于点小于右儿子。

    于是,BST能够支持的操作:

    加点(不用说了)

    找前驱(小于一个值的最大值)

    找后继(大于一个值得最小值)

    根据排名找值

    根据值找排名。

    直接上代码,理解讲解都在注释里(只给各个函数的代码了)

    struct tree
    {
        int ls,rs,size,cnt,val;
    }t[maxn];
    
    
    
    //以下为加点 
    //size表示当前节点的子树大小和自己的大小的和,
    //cnt表示当前节点代表的数有几个
    void add(int now,int val)//now为当前遍历的点的编号,val为点权值 
    {
        t[now].size++;
        if(t[now].val==val)
        {
            t[now].cnt++;//多个相同值得点,不增加点了 
            return;
        }
        if(t[now].val>val)
        {
            if(t[now].ls!=0)
            {
                addedge(t[now].ls,val);
            }
            else
            {
                cnt++;
                t[cnt].size=1;
                t[cnt].val=val;
                t[cnt].cnt=1;
                t[now].ls=cnt;
            }
        }
        else
        if(t[now].val<val)//根据二叉查找树的性质来插值 
        {
            if(t[now].rs!=0)//如果不是叶子节点 
            {
                addedge(t[now].rs,val);//向下寻找叶子节点再插入 
            }
            else
            {
                cnt++;//cnt为点的编号 
                t[cnt].size=1;//找前驱的东西 
                t[cnt].val=val;//存值 
                t[cnt].cnt=1;//有几个相同的值 
                t[now].rs=cnt;//点的编号,右儿子加点 
            }
        }
    }
    int getqianqu(int now,int val,int ans)
    {
        if(t[now].val>=val)//如果当前值大于正在被寻找前驱的值 
        {//那么可以判定:前驱一定是在它的左子树中 
            if(t[now].ls==0)//如果没有左子树 
            {
                return ans;//当前值就是答案 
            }
            else //否则 
            {
                getqianqu(t[now].ls,val,ans);//在左子树中找答案 
            }
        }
        else if(t[now].val<val)//如果当前值小于正在被寻找前驱的值 
        {//那么可以判定:前驱一定在它的右子树中 ,一路小过来,小过了,往大值试探 
            if(t[now].rs==0)//如果没有右子树 
            {
                if(t[now].val<val)//如果当前值小于正在被寻找前驱的值 
                {
                    return t[now].val;//在没有右子树的情况下,当前点就是前驱 
                }
                else
                {
                    return ans;//否则前面点就是前驱 
                }
            }
            if(t[now].cnt!=0)//删点之后..在treap里的操作,这里没有 
            {
                return getqianqu(t[now].rs,val,t[now].val);
            }
            else
            {
                return getqianqu(t[now].rs,val,ans);
            }
        }
    }
    int gethouji(int now,int val,int ans)
    {
        if(t[now].val<=val)//如果当前值大于正在被寻找前驱的值 
        {
            if(t[now].rs==0)//如果没有左儿子 
            {
                return ans;
            }
            else 
            {
                gethouji(t[now].rs,val,ans);
            }
        }
        else if(t[now].val>val)
        {
            if(t[now].ls==0)
            {
                if(t[now].val>val)
                {
                    return t[now].val;
                }
                else
                {
                    return ans;
                }
            }
            if(t[now].cnt!=0)
            {
                return gethouji(t[now].ls,val,t[now].val);
            }
            else
            {
                return gethouji(t[now].ls,val,ans);
            }
        }
    }
    //size表示当前节点的子树大小和自己的大小的和,
    //cnt表示当前节点代表的数有几个
    int nth(int now,int rank)
    {
        if(now==0)//0,没有值 
        {
            return 0x7fffffff;
        }
        if(t[t[now].ls].size>rank)//如果左子树的子树的大小大于nth 
        {
            return nth(t[now].ls,rank);//去找左子树 
        }
        if(t[t[now].ls].size+t[now].cnt>=rank)//如果左子树的子树的大小+当前节点(重复节点)大于等于nth 
        {
            return t[now].val;//那这个点就是nth 
        }
        return nth(t[now].rs,rank-t[t[now].ls].size-t[now].cnt);//找子树中nth-子树大小的值 
    }
    int valth(int now,int val)
    {
        if(now)==0)
        {
            return 0;
        }
        if(val==t[now].val)
        {
            return t[t[now].ls].size+1;
        }
        if(val<t[now].val)
        {
            return valth(t[now].ls,val);
        }
        return valth(t[now].rs,val)+t[t[now].ls].size+t[now].cnt;
    }//基本同理于kth 

    (完)

  • 相关阅读:
    AHOI2012 信号塔 | 最小圆覆盖模板
    BZOJ1337 最小圆覆盖
    HAOI2014 走出金字塔
    HAOI2012 外星人
    HAOI2014 遥感监测
    HAOI2012 道路
    NOI2007 社交网络
    HAOI2012 高速公路
    HAOI2012 容易题
    HAOI2011 Problem c
  • 原文地址:https://www.cnblogs.com/ajmddzp/p/10957983.html
Copyright © 2011-2022 走看看