平衡树学习笔记

查找

静态查找

1.顺序查找 (n)
2.二分查找 (log n)
3.哈希

动态查找

二叉查找树BST(Binary Search Tree)

二叉查找树

二叉查找树又称二叉排序树

定义

空树或者是具有如下特性的二叉树:

1.若它的左子树不空,则左子树上所有结点的值均小于根结点的值;
2.它的右子树不空,则右子树上所有结点的值均大于根结点的值;
3.它的左、右子树也都分别是二叉查找树。

例子

初始化

struct NOTE
{
    int l,r,key,val;
}

查找

找最值

这里只列举找最大值的方法,找最小值类似。

迭代方法

void findMax()
{
    int now=1;
    while(t[t[now].r].val!=-1) //及判断树的右节点是否有值
    {
        now=t[now].r;
    }
    return t[now].val;
}

递归方式

void findMax(int now)
{
    if(t[t[now].r].val!=-1)
    {
        findMax(t[now].r);
    }
    else return t[now].val;
}

查找比x大(小)的最小(大)值

比x小的最大值。
迭代方法

int findMinm(int w)
{
    int x=root;
    int y=0;
    while (x!=-1)
        if (t[x].val<w)
        {
            y=t[x].val;
            x=t[x].r;
        }
        else x=t[x].l;
    return y;
}

插入

把X插入树T中,像Find那样沿着树找。如果找到X,则什么也不用做(或做一些更新),否则将X插入到遍历的路径上最后一个结点上,新插入的结点一定是叶子结点(只需改动一个结点的指针),该叶子结点是查找不成功时路径上访问的最后一个结点左孩子或右孩子(新结点值小于或大于该结点值)
但是如果只是这么做很有可能会超时,因为平衡树有可能会退化成O(n),准确来说是很有可能。
然后我们就可以给节点随机分配一个优先级,先和二叉搜索树的插入一样,先把要插入的点插入到一个叶子上,然后跟维护堆一样,如果当前节点的优先级比根大就旋转,如果当前节点是根的左儿子就右旋如果当前节点是根的右儿子就左旋。
由于旋转是O(1)的,最多进行h次(h是树的高度),插入的复杂度是O(h)的,在期望情况下h=O(log n),所以它的期望复杂度是O(log n)。
于是得到了以下代码

void rttr(int &dep)
{
    int y=t[dep].l;
    t[dep].l=t[y].r;
    t[y].r=dep;
    dep=y;
}

void rttl(int &dep)
{
    int y=t[dep].r;
    t[dep].r=t[y].l;
    t[y].l=dep;
    dep=y;
}

void insert(int &dep,ll x)
{
    if(!dep)
    {
        dep=++tot;
        t[tot].val=x;
        t[tot].key=rand();
        return ;
    }
    if(t[dep].val==x)
        return ;
    if(t[dep].val>x)
    {
        insert(t[dep].l,x);
        if(t[t[dep].l].key<t[dep].key)
            rttr(dep);
    }
    else
    {
        insert(t[dep].r,x);
        if(t[t[dep].r].key<t[dep].key)
            rttl(dep);
    }
}

习题

bzoj 3544: [ONTAK2010]Creative Accounting treap
blog http://blog.csdn.net/qq_33229466/article/details/53614337
set
http://hzwer.com/6391.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值