不想用treap和Splay,那就用SB树把,哈哈,其实它一点也SB,厉害着呢。

先膜拜一下作者陈启峰。Orz

以下内容由我搜集整理得来。

一、BST及其局限性


二叉查找树(Binary Search Tree),也称有序二叉树(ordered binary tree),排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:

1.若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;

2.任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;

3.任意节点的左、右子树也分别为二叉查找树。

4.没有键值相等的节点(no duplicate nodes)。
二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低。为O(log n)
但是,缺点是若待插入的序列是有序的,那么它会退化成单链表!这样查询时间将会为O(n)!
解决办法有很多改进版的二叉查找树可以使树高为O(logn),如SBT,AVL,红黑树,treap等
红黑树和AVL比较复杂,不太适合在算法竞赛中使用。
基本平衡思想如下:

右旋的伪代码

右旋操作假定左儿子存在。

Right-Rotate(t)
k ← left[t]
left[t] ← right[k]
right[k] ← t
s[k] ← s[t]
s[t] ← s[left[t]] + s[right[t]] + 1
t ← k

左旋的伪代码

左旋操作假定右儿子存在。

Left-Rotate(t)
k ← right[t]
right[t] ← left[k]
left[k] ← t
s[k] ← s[t]
s[t] ← s[left[t]] + s[right[t]] + 1
t ← k

二、SBT

Size Balanced Tree(简称SBT)是一种平衡二叉搜索树,它通过子树的大小s[t]来维持平衡性质。它支持很多动态操作,并且都能够在O(log n)的时间内完成。
为了下面方便讨论,
我们设
left [T] : 结点 T 的左儿子

right [T] : 结点 T 的右儿子

s [T] : 以T为根的子树的结点个数(大小))

SBT为什么能保持平衡?
  因为 对于SBT的每一个结点 t,有如下性质:
   性质(a) s[ right[t] ]≥s[ left [ left[ t ] ] ], s[ right [ left[t] ] ]

   性质(b) s[ left[t] ]≥s[right[ right[t] ] ], s[ left[ right[t] ] ]


即.每棵子树的大小不小于其兄弟的子树大小。(对于数组来实现树不熟悉的童鞋,请把s[ left [ left[ t ] ] ] 翻译为s[ t->left->left ] 同样的,s[ right [ left[t] ] ]翻译为s[ t->left->right ] )

如上图有s[A],s[B]≤s[R]和s[C],s[D] ≤s[L]

1.平衡维护mantain

在执行完简单的插入之后,性质a或性质b可能就不满足了,于是我们需要调整SBT。

Maintain (T) 用于修复以 T 为根的 SBT 。由于性质(a)和(b)是对称的,下面仅讨论对性质(a)的修复。

Case 1: s[ Left[ Left[ T ] ]>s[ Right[ T ] ]

在下图中,就是说 s[A]>s[R]

首先执行右旋(Right-Rotate (T))可得

有可能旋转后的树仍然不是SBT,需要再次执行Maintain(T)



由于L的右儿子发生了变化,因此需要执行Maintain(L)
也就是说,这种情况先执行一次Right-Rotate (T),接着执行Maintain (T) 保证T为SBT,然后执行Maintain(L),保证L为SBT

Case 2: s[ right[ left[ t ] ]>s[ right[ t ] ]

在下图中,也就是说 s[B]>s[R]

先执行左旋Left-Rotate(L)。如下图



执行右旋Right-Rotate(T),如下图:

接着执行Maintain (L) 和Maintain (T),来保证L和T是SBT
同理执行Maintain (B)

Case 3:s[ right[ right[ t ] ] ]>s[ left[ t ] ]

 这个和case 1是对称的。。。。

Case 4:s[ left[ right[ t ] ] ]>s[ left[ t ] ]

这个和case 2是对称的。。



可写出C++代码如下,感觉比伪代码好看。。。
void matain(int &t)
{
if(size[ left[ left[t] ] ] > size[ right[t] ] )
{
right_rotate(t);
matain(right[t]);
matain(t);
}
else if( size[ right[ left[t] ] ]>size[ right[t] ] )
{
left_rotate(left[t]);
right_rotate(t);
matain(left[t]);
matain(right[t]);
matain(t);
}
else if(size[ right[ right[t] ] ]>size[ left[t] ])
{
left_rotate(t);
matain(left[t]);
matain(t);
}
else if(size[ left[ right[t] ] ]>size[ left[t] ])
{
right_rotate(right[t]);
left_rotate(t);
matain(left[t]);
matain(right[t]);
matain(t);
}
}

有了维护操作后,接下来的步奏就很简单了。

2.插入insert

Insert (t,v)
If t=0 then
t ← NEW-NODE(v)
Else
s[t] ← s[t]+1
If v<key[t] then
Simple-Insert(left[t],v)
Else
Simple-Insert(right[t],v)
Maintain(t,v≥key[t])

3.删除delete

如果没有找到要删除的结点,那么就删除最后一个访问的结点并记录。

Delete (t,v)
s[t] ←s[t]-1
If (v=key[t])or(v<key[t])and(left[t]=0)or(v>key[t])and(right[t]=0) then
Delete ←key[t]
If (left[t]=0)or(right[t]=0) then
t ←left[t]+right[t]
Else
key[t] ←Delete(left[t],v[t]+1)
Else
If v<key[t] then
Delete(left[t],v)
Else
Delete(right[t],v)
Maintain(t,false)
Maintain(t,true)


由于SBT的性质(结点t的关键字比其左子树中所有结点的关键字都大,比其右子树中所有的关键字都小),理解下面的算法非常容易。

4.Select操作

返回在第k位置上的结点(即返回根为t的树中排名为k的结点。)。显然它包括了取大(Maximum)和取小(Minimun),取大等价于Select(t,1),取小等价于Select(t,s[t])。
Select(t,k)
If k=s[left[t]]+1 then
return key[t]
If k<=s[left[t]] then
return Select(left[t],k)
Else
return Select(right[t],k-1-s[left[t]])

5.Rank操作

返回v在以t为根的树中的排名,也就是比v小的那棵树的大小(Size)加一。
Rank(t,v)
If t=0 then
return 1
If v<=key[t] then
return rank(left[t],v)
Else
return s[left[t]]+1+rank(right[t],v)

6.其他的

证明什么的就不说啦,有兴趣的可以看作者原论文。
结论就是:

1.SBT的高度为O(logn)

2.Maintain的平摊运行时间是:O(1)


一个用SBT树解决第K大元素的例子


Size Balanced Tree(SBT树)整理的更多相关文章

  1. Size Balanced Tree

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

  2. Size Balanced Tree(SBT) 模板

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

  3. C基础 - 终结 Size Balanced Tree

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

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

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

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

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

  6. Size Balanced Tree(节点大小平衡树)

    定义 SBT也是一种自平衡二叉查找树,它的平衡原理是每棵树的大小不小于其兄弟树的子树的大小 即size(x->l)$\ge$size(x->r->l),size(x->r-&g ...

  7. Size Balance Tree(SBT模板整理)

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

  8. 56. 2种方法判断二叉树是不是平衡二叉树[is balanced tree]

    [本文链接] http://www.cnblogs.com/hellogiser/p/is-balanced-tree.html [题目] 输入一棵二叉树的根结点,判断该树是不是平衡二叉树.如果某二叉 ...

  9. [转] Splay Tree(伸展树)

    好久没写过了,比赛的时候就调了一个小时,差点悲剧,重新复习一下,觉得这个写的很不错.转自:here Splay Tree(伸展树) 二叉查找树(Binary Search Tree)能够支持多种动态集 ...

随机推荐

  1. 迅雷云监工crysadm搭建

    之前在淘宝众筹买了个迅雷赚钱宝Pro,2016年01月到手,玩了半个月. 之后在看百度贴吧时,看到好多大神都在用PC上用网页版软件来管理赚钱宝.非常是好奇.搜索了非常多资料,基本上都已经过时了.都无法 ...

  2. userAgent判断客户端,以及各个浏览器的ua

    userAgent判断客户端,以及各个浏览器的ua http://blog.csdn.net/yoyoosyy/article/details/70142884 navigator.userAgent ...

  3. if 的理解

    1. if 实现集合的划分 比如著名的 Prim 算法(最小生成树),从某一确定的点出发,每次新加入的点,都是在已访问过的结点(u∈U)和未访问过(v∈V−U)的结点之间的边.这里的未被访问(V−U) ...

  4. 在Qt Creator的项目中添加头文件和库

    在Qt Creator中的工程中,工程通过.pro文件管理. 额外需要连接的连接库unix:LIBS += -L your_lib_path -lyour_libwin32:LIBS += your_ ...

  5. Android 打造属于自己的RxBus

    RxBus 通过RxJava实现Rxbus. 相信大家已经非常熟悉EventBus了.最近正在学习Rxjava,如果在项目中已经使用了Rxjava,使用RxBus来代替EventBus应该是不错的选择 ...

  6. material风格前端CSS框架——Materialize

    官方网站:http://materializecss.com/(有中文,翻译不全) 中文学习站:http://www.materializecss.cn/(翻译较全)

  7. 【2017 Multi-University Training Contest - Team 9】FFF at Valentine

    [链接]http://acm.hdu.edu.cn/showproblem.php?pid=6165 [题意] 一张有向图,n个点,m条边,保证没有重边和自环.询问任意两个点能否满足任何一方能够到达另 ...

  8. 【2017中国大学生程序设计竞赛 - 网络选拔赛】A Secret

    [链接]http://acm.hdu.edu.cn/showproblem.php?pid=6153 [题意] ,S2中出现的次数与其长度的乘积之和.  [题解] 扩展KMP的模板题. 首先,把S2和 ...

  9. [NPM] Test npm packages locally in another project using npm link

    We will import our newly published package into a new project locally to make sure everything is wor ...

  10. textview-显示行数限制

    在代码中直接添加 android:maxLines="2" android:ellipsize="end" 跟ellipsize搭配使用,超过两行的时候,第二行 ...