今天上网搜索关于红黑树的资料时,发现一种新的平衡二叉树(SBT),据说各方面性能很好,先摘录在此,以后再细看。

Size Balanced Tree(SBT)是一种平衡二叉查找树。它的论文由中国广东中山纪念中学的陈启峰于2006年底完成,并在Winter Camp 2007中发表。由于SBT的拼写很容易找到中文谐音,它常被中国的OIer们戏称为“傻X树”、“Super BT”等。但它的性能并不SB,编写起来也并不BT。恰恰相反,SBT易于实现,且据陈启峰论文中所言,“这是目前为止速度最快的高级二叉搜索树”。它能在O(logn)的时间内完成所有BST的相关操作。而且由于SBT赖以保持平衡的是Size域而不是其他“无用”的域,它可以很方便地实现动态顺序统计中的select和rank。

目录
[隐藏]
1 性质
2 旋转
2.1 左旋转
2.2 右旋转
3 保持性质(Maintain)
4 基本操作
4.1 查找
4.2 取大/取小
4.3 后继
4.4 前趋
4.5 插入
4.6 删除
5 动态顺序统计操作
5.1 检索具有给定排序的元素
5.2 求元素的秩
6 性能分析
7 源码
8 参考资料

[编辑] 性质
Size Balanced Tree(SBT)是一种通过大小(Size)域来保持平衡的二叉搜索树,它也因此得名。它总是满足:
对于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]]]
即每棵子树的大小不小于其兄弟的子树大小。

图1
如图(圈代表结点,三角代表SBT,下同):

s[R] ≥ s[A] , s[B]
s[L] ≥ s[C] , s[D]
[编辑] 旋转
SBT的旋转(Rotations)与其他高级BST相同。它是下面提到的Maintain操作的基础。

图2
[编辑] 左旋转
Left-Rotate (t)

1     k ← right[t]
2     right[t] ← left[k]
3     left[k] ← t
4     s[k] ← s[t]
5     s[t] ← s[left[t]] + s[right[t]] + 1
6     t ← k
[编辑] 右旋转
Right-Rotate(t)

1     k ← left[t]
2     left[t] ← right[k]
3     right[k] ← t
4     s[k] ← s[t]
5     s[t] ← s[left[t]] + s[right[t]] + 1
6     t ← k
[编辑] 保持性质(Maintain)
当我们插入或删除一个结点后,SBT的大小就发生了改变。这种改变有可能导致性质(a)或(b)被破坏。这时,我们需要用Maintain操作来修复这棵树。Maintain操作是SBT中最具活力的一个独特过程;Maintain(T)用于修复以T为根的 SBT。调用Maintain(T)的前提条件是T的子树都已经是SBT了。
我们需要讨论的有4种情况。由于性质a和性质b是对称的,所以我们仅仅详细的讨论性质a。

第一种情况:s[left[left[t]]>s[right[t]]

图3(同图1)
如图3,执行完Insert(left[t],v)后发生S[A]>S[R],我们可以执行以下的指令来修复SBT:
首先执行Right-Ratote(t),这个操作让图3变成图4;

图4
在这之后,有时候这棵树还仍然不是一棵SBT,因为 或者 也是可能发生的。所以就有必要继续调用Maintian(t)。
结点L的右子树有可能被连续调整,因为有可能由于性质的破坏需要再一次运行Maintain(L)。

第二种情况:s[right[left[t]]>s[right[t]]

图5
在执行完Insert(left[t],v)后发生s[B]>s[R],如图5,这种调整要比情况1复杂一些。我们可以执行下面的操作来修复:
在执行完Left-Ratote(L)后,图5就会变成下面图6那样了。

图6
然后执行Right-Ratote(T),最后的结果就会由图6转变成为下面的图7。

图7
在第1步和第2步过后,整棵树就变得非常不可预料了。万幸的是,在图7中,子树A、E、F和R仍就是SBT,所以我们可以调用Maintain(L)和Maintain(T)来修复结点B的子树。
在第3步之后,子树都已经是SBT了,但是在结点B上还可能不满足性质a或性质b,因此我们需要再一次调用Maintain(B)。

第三种情况:s[right[right[t]]>s[left[t]]
与情况1对称。
第四种情况:s[left[right[t]]>s[left[t]]
与情况2对称。

通过前面的分析,很容易写出一个普通的Maintain。

Maintain (t)

01     If s[left[left[t]]>s[right[t]] then    //case1
02          Right-Rotate(t)
03          Maintain(right[t])
04          Maintain(t)
05          Exit
06     If s[right[left[t]]>s[right[t]] then   //case2
07          Left-Rotate(left[t])
08          Right-Rotate(t)
09          Maintain(left[t])
10          Maintain(right[t])
11          Maintain(t)
12          Exit
13     If s[right[right[t]]>s[left[t]] then   //case1'
14          Left-Rotate(t)
15          Maintain(left[t])
16          Maintain(t)
17          Exit
18     If s[left[right[t]]>s[left[t]] then    //case2'
19          Right-Rotate(right[t])
20          Left-Rotate(t)
21          Maintain(left[t])
22          Maintain(right[t])
23          Maintain(t)

前面的标准过程的伪代码有一点复杂和缓慢。通常我们可以保证性质a和性质b的满足,因此我们只需要检查情况1和情况2或者情况3和情况4,这样可以提高速度。所以在那种情况下,我们需要增加一个布尔(boolean)型变量:flag,来避免毫无意义的判断。如果flag是false,那么检查情况1和情况2;否则检查情况3和情况4。

Maintain (t,flag)

01     If flag=false then
02          If s[left[left[t]]>s[right[t]] then      //case1
03               Right-Rotate(t)
04          Else
05               If s[right[left[t]]>s[right[t]] then   //case2
06                    Left-Rotate(left[t])
07                     Right-Rotate(t)
08          Else                                   //needn’t repair
09               Exit
10     Else
11          If s[right[right[t]]>s[left[t]] then      //case1'
12               Left-Rotate(t)
13          Else
14               If s[left[right[t]]>s[left[t]] then     //case2'
15                    Right-Rotate(right[t])
16                    Left-Rotate(t)
17          Else                                    //needn’t repair
18               Exit
19     Maintain(left[t],false)                     //repair the left subtree
20     Maintain(right[t],true)                     //repair the right subtree
21     Maintain(t,false)                           //repair the whole tree
22     Maintain(t,true)                            //repair the whole tree
为什么Maintain(left[t],true)和Maintain(right[t],false)被省略了呢?您可以在陈启峰论文第六部分的分析中找到答案。
其他可以从论文中获得的信息:每次SBT后树的总深度递减的证明;Maintain的平摊运行时间是O(1)的证明(也就是说你不必担心Maintain这个递归过程是否会永不停止)等。

[编辑] 基本操作
[编辑] 查找
SBT的查找操作与普通BST完全相同。下面的过程将返回指向目标节点的指针。

Search(t,k)

1     if x=NIL or k=key[t]
2        then return x
3     if k<key[x]
4        then return Search(left[x],k)
5        else return Search(right[x],k)
[编辑] 取大/取小
由于SBT本身已经维护了size,因此这两项可用Select操作完成。

[编辑] 后继
SBT的后继操作与普通BST完全相同。

[编辑] 前趋
SBT的前趋操作与普通BST完全相同。它与上面的后继操作对称。

[编辑] 插入
SBT的插入操作很简单。它仅仅比普通BST的多出了一个Maintain操作和对s的简单维护。下面这个过程将一个节点v插入SBT中。

Insert (t,v)

1     If t=0 then
2        t ← v
3     Else
4        s[t] ← s[t]+1
5         If v<key[t] then
6              Simple-Insert(left[t],v)
7         Else
8             Simple-Insert(right[t],v)
9     Maintain(t,v≥key[t])
[编辑] 删除
与普通维护size域的BST删除相同。
关于无需Maintain的说明by sqybi:
在删除之前,可以保证整棵树是一棵SBT。当删除之后,虽然不能保证这棵树还是SBT,但是这时整棵树的最大深度并没有改变,所以时间复杂度也不会增加。这时,Maintain就显得是多余的了。

[编辑] 动态顺序统计操作
由于SBT本来就是靠着size域来维持平衡的,当我们进行动态顺序统计操作时,我们就无需去“额外”维护一个size域来进行数据结构的扩张。这样,以下操作就与其他高级BST扩张后的动态顺序统计操作完全一样了。

[编辑] 检索具有给定排序的元素
下面这个过程将返回一个指向以x为根的子树中包含第i小关键字的节点的指针。

Select(x,i)

1     r ← size[left[x]] + 1
2     if(i=r)
3          then return x
4     else if i<r
5          then return Select(left[x],r)
6     else return Select(right[x],i-r)
[编辑] 求元素的秩
SBT的rank操作与普通BST完全相同。

[编辑] 性能分析
SBT的高度是O(logn),Maintain是O(1),所有主要操作都是O(logn)。

[编辑] 源码
C
C++
Pascal

[编辑] 参考资料
[Size Balanced Tree], 陈启峰
Size Balanced Tree, 陈启峰, Translated by BambooLeaf
Introduction to Algorithms

来自"http://www.nocow.cn/index.php/Size_Balanced_Tree"

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/adcxf/archive/2008/08/02/2758691.aspx

陈启峰 Size Balanced Tree相关推荐

  1. C基础 - 终结 Size Balanced Tree

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

  2. size balanced tree (平衡二叉树) ----- 傻X树----陈启峰论文

    Size Balanced Tree(SBT)是一种平衡二叉查找树.它的论文由中国广东中山纪念中学的陈启峰于2006年底完成, 并在Winter Camp 2007中发表.由于SBT的拼写很容易找到中 ...

  3. Size Balanced Tree

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

  4. 照片有灵异鬼影?伯克利 x 陈启峰培育高能FCN“除灵师” | CVPR论文

    家栗子 发自 航天桥 量子位 出品 | 公众号 QbitAI 古人云,捕风捉影. 捕风或许不那么容易,毕竟,能停下来的,就不是风了. 捉影的话,可以把神经网络放出来,它们的视觉可以很灵敏. 不过,神经 ...

  5. CQF平衡树——SBT论文——Size Balanced Tree

    Size Balanced Tree Size Balanced Tree(SBT)是一种平衡二叉查找树.它的论文由中国广东中山纪念中学的陈启峰于2006年底完成,并在Winter Camp 2007 ...

  6. 竞赛最好用的平衡树-Size Balanced Tree(SBT)【建议收藏】

    大家好. 前段时间我更新过AVL.红黑树以及搜索二叉树的简单讲解.今天我们还是围绕着平衡树的话题,来讲解一个很牛逼的平衡树结构.这种结构是我国的一位大牛:陈启峰.在2006年,他还在读高中阶段,所发明 ...

  7. 陈启峰:人工智能生成图像技术,未来或能取代电影特效

    2019年1月21日,<麻省理工科技评论>公布了2018年"35岁以下创新35人"(Innovators Under 35 China)中国区榜单.从榜单中,我们看到更 ...

  8. 姚班系创业公司宸镜科技再获新融资,漆子超、陈启峰联手,OPPO入股加持“元宇宙”概念要火?...

    贾浩楠 发自 凹非寺 量子位 报道 | 公众号 QbitAI 国内堪称最强"明星光环"AR创业公司宸镜科技,刚刚完成成立2年来第三轮融资. 总额数千万美元,OPPO.斯道资本(Ei ...

  9. 姚班天才漆子超、IOI金牌得主陈启峰等联手进军AR领域:全员顶尖科技公司技术背景,打造“5G+AI+AR”先锋...

    鱼羊 发自 凹非寺 量子位 报道 | 公众号 QbitAI 最新消息,AR领域又有明星玩家入局. 清华姚班毕业.IOI 2009金牌得主漆子超,斯坦福博士.IOI 2007金牌得主陈启峰均在联合创始人 ...

最新文章

  1. linux之cut命令详解
  2. Boost:使用boost :: hash和boost :: array的测试
  3. flashback_transaction_query查询权限
  4. 监控和剖析数据库操作P6Spy,SQL Profiler,SQL 使用简介
  5. 操作系统文件管理_计算机民科笔记-操作系统week1
  6. puppet详解(一)——puppet基础知识
  7. 第102天:CSS3实现立方体旋转
  8. 使用监听器生成请求记录日志
  9. ad17如何删除3d实体_多年工作积累的Altium AD09 AD17 硬件元器件 原理图库+PCB封装库...
  10. 拉普拉斯矩阵与正则化
  11. Qt高质量的开源项目合集
  12. 八类网线和七类网线的区别_Cat8 八类网线是什么?与Cat5、Cat6、Cat7网线的区别?...
  13. 微信电话语音质量 VS VOLTE语音质量
  14. 【Unity3D 灵巧小知识点】 ☀️ | Unity中几个简单又常见的报错异常
  15. python主程序退出方法quit()
  16. Uber实时大数据系统架构分析-Kafka-Samza-Siddhi
  17. java 体检套餐_体检套餐管理系统的综合版
  18. 查看git的远程主机名_git pull 主机名
  19. JavaSE自学笔记
  20. 计算机硕士论文,盲审的老师都很严吗? - 易智编译EaseEditing

热门文章

  1. 对抗样本论文学习:Deep Neural Networks are Easily Fooled
  2. 面试 以及面试中对公司更好的了解
  3. 硬件学习之路-改善稳压电路的动态响应
  4. 糖尿病预测模型-Pima印第安人数据集-论文_企业科研
  5. Ant Design 省市区联动数据
  6. 如何寻求解脱_在设计中寻求安慰
  7. Canvas——文字绘制
  8. cc链2(小宇特详解)
  9. 电商双十一购物节促销活动及短信营销解决方案
  10. Ubuntu 22.04 LTS 现在可供下载