Size Balanced Tree(SBT)是目前速度最快的平衡二叉搜索树,且能够进行多种搜索操作,区间操作;和AVL、红黑树、伸展树、Treap类似,SBT也是通过对节点的旋转来维持树的平衡,而相比其他平衡树,SBT维持平衡所需要的额外数据很少,只需要维持以当前节点为根的子树的大小;且SBT的编写复杂度低。因此具有空间优势、速度优势、编写优势。

SBT的节点

SBT节点维持很少的额外信息,只需要知道以当前节点为根的子树的大小。

    struct TreeNode{
int data;
TreeNode* child[2];
int size; //以该节点为根的子树的大小(节点的个数)
TreeNode(int d){
data = d;
child[0] = child[1] = NULL;
size = 1;
}
};

SBT的平衡性质

一棵平衡的SBT树满足如下要求:

记S[t]为以节点t为根的子树的大小,则对于每个节点T,记其左子节点L, 右子节点R, 左子结点的左子结点LL, 左子结点的右子节点LR, 右子节点的左子结点RL, 右子节点的右子节点RR。 
    则有, S[L] >= max(S[RL], S[RR]), S[R] >= max(S[LL], S[LR]). 
即任何一个节点的size均大于等于其侄子节点的size。 (侄子节点:定义为一个节点的兄弟节点的两个子节点)

SBT的维护操作

一棵平衡的SBT在进行插入和删除之后,可能会不再平衡,此时需要进行维护操作,维护操作需要进行左旋或者右旋操作,旋转操作和其他平衡树的旋转类似(具体见zig-zag旋转) . 
    SBT的非平衡情况分为两类:左子结点和左子结点的侄子节点不平衡或者右子节点和右子节点的侄子节点不平衡。这里以右子节点和右子节点的侄子节点为例,进行Maintain操作。 
    失衡情形1:    S[LL] > S[R] 
 
(1)执行 RightRotate(T),得到如下结果 
 
(2)此时以T为根的树可能不平衡,递归调用Maintain(T) 
 
(3)此时T成为平衡SBT, 再次对L调用Maintain(L)将整体变为平衡SBT 

失衡情形2:    S[LR] > S[R] 
 
(1)执行 LeftRotate(L),得到如下结果 
 
(2)执行 RightRotate(T),得到如下结果 
 
(2)此时以B和R为根的树可能不平衡,递归调用Maintain(B)、Maintain(R) 
 
(3)此时T成为平衡SBT, 再次对L调用Maintain(L)将整体变为平衡SBT 

由于Maintain操作是个递归执行的函数,貌似可能会出现无限循环,但实际上,陈启峰在论文里分析过了,Maintain操作的平坦复杂度为O(1)。因此Maintain操作不会出现无法结束的情况。

SBT的其他操作

和其他的二叉搜索树一样,SBT支持插入、删除、查找等操作。插入和删除操作可能会破坏SBT的平衡性质,因此,需要在普通的插入和删除之后对节点进行维护,即调用Maintain函数。

实现(c++)

#include<iostream>
using namespace std;
struct TreeNode{
int data;
TreeNode* child[2];
int size;
int count;
TreeNode(int d){
data = d;
child[0] = child[1] = NULL;
size = count = 1;
}
void Update(){
size = count;
if (child[0]){
size += child[0]->size;
}
if (child[1]){
size += child[1]->size;
}
}
};
struct SBT{
TreeNode* root;
SBT() :root(NULL){}; void Rotate(TreeNode*& node, int dir){
TreeNode* ch = node->child[dir];
node->child[dir] = ch->child[!dir];
ch->child[!dir] = node;
node = ch;
}
//返回node节点为根的子树的大小
int GetSize(TreeNode* node){
if (node)
return node->size;
return 0; //对于空节点,直接返回0
} //维持平衡
void Maintain(TreeNode*& node, bool flag){
TreeNode* R = node->child[1];
TreeNode* L = node->child[0];
TreeNode* LL = NULL,*LR = NULL,*RL = NULL,*RR = NULL;
if (L){
LL = L->child[0];
LR = L->child[1];
}
if (R){
RL = R->child[0];
RR = R->child[1];
} if (flag == false){ //左边维护
if (GetSize(LL) > GetSize(R)){ //失衡情况1
Rotate(node, 0);
}
else if (GetSize(LR) > GetSize(R)){ //失衡情况2
Rotate(L, 1);
Rotate(node, 0);
}
else{
return; //不失衡,直接返回
}
}
else{
if (GetSize(RR) > GetSize(L)){
Rotate(node, 1);
}
else if (GetSize(RL) > GetSize(L)){
Rotate(R, 0);
Rotate(node, 1);
}
else
{
return;
}
}
Maintain(node->child[0], false); //继续将 左子树维持平衡,注意这里不能直接使用L,因为之前进行了旋转操作
Maintain(node->child[1], true); //继续将 右子树维持平衡
Maintain(node, true); //再维持 node
Maintain(node, false);
} void Insert(TreeNode*& node, int data){
if (!node){
node = new TreeNode(data);
return;
}
else if (node->data == data){
node->count++;
node->Update(); //更新本节点以及其祖先节点的size
return;
}
else {
int dir = node->data < data;
Insert(node->child[dir], data); Maintain(node, ! dir);
//如果新插入的数据 小于 当前节点的数据,则被插入左子树,
//此时左子树的左右子节点的size可能大于右子节点,因此Maintain(x, false) node->Update();
}
} void Delete(TreeNode*& node, int w){
if (!node){
return;
}
if (node->data == w){
if (node->child[0] && node->child[1]){
TreeNode* succ = node->child[1];
while (succ->child[0]){
succ = succ->child[0];
}
node->data = succ->data;
succ->data = w;
Delete(node, w);
}
else{
TreeNode* tmp_node = NULL;
if (node->child[0])
tmp_node = node->child[0];
else
tmp_node = node->child[1];
delete node;
node = tmp_node;
}
}
Maintain(node, false);
node->Update();
} };

参考: 
SBT-陈启峰

Size Balanced Tree的更多相关文章

  1. Size Balanced Tree(SBT) 模板

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

  2. C基础 - 终结 Size Balanced Tree

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

  3. Size Balanced Tree(SBT树)整理

    不想用treap和Splay,那就用SB树把,哈哈,其实它一点也SB,厉害着呢. 先膜拜一下作者陈启峰.Orz 以下内容由我搜集整理得来. 一.BST及其局限性 二叉查找树(Binary Search ...

  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. 重学数据结构系列之——平衡树之SB Tree(Size Blanced Tree)

    学习来源:计蒜客 平衡树 1.定义 对于每一个结点.左右两个子树的高度差的绝对值不超过1,或者叫深度差不超过1 为什么会出现这样一种树呢? 假如我们依照1-n的顺序插入到二叉排序树中,那么二叉排序树就 ...

随机推荐

  1. 【C#】往按钮事件中传递自定义参数

    情景:代码动态生成的按钮,需要自定义点击事件.但是生成的点击事件的参数是固定的,如何才能传入自定义的参数? Button btn = new Button() { Content = "这是 ...

  2. Phalcon学习-model

    Model:表与表之间的关系:hasOne 一对一( $fields, $referenceModel, $referencedFields : 当前表中的字段, 对应关系模型, 对应关系模型中表的字 ...

  3. MongoDB之分片

    本文介绍分片的思想和MongoDB中的实现方法. 首先须要介绍一些主要的概念. 分片 分片.也叫做分区.是一种经常使用的数据库优化技术.其含义就是将数据拆分,将数据分散到不同机器上的过程.这样就能够使 ...

  4. Swift开发教程--设置UIViewController的背景透明

    非常easy的一句代码 self.view.backgroundColor = UIColor.clearColor() 由此联想开来,非常多的控件想设置为背景透明都能够用UIColor.clearC ...

  5. MySQL 性能优化的最佳 20+ 条经验

    今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我 们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数 ...

  6. AJAX跨域请求json数据的实现方法

    这篇文章介绍了AJAX跨域请求json数据的实现方法,有需要的朋友可以参考一下 我们都知道,AJAX的一大限制是不允许跨域请求. 不过通过使用JSONP来实现.JSONP是一种通过脚本标记注入的方式, ...

  7. 关于SQL语句的一些注意事项

    1.Into 表后要编辑-IntelliSense-刷新本地缓存 才能访问新表 2.Is null不是=null

  8. [转载]如何解决failed to push some refs to git

    Administrator@PC-20150110FGWU /K/cocos2d/yc (master) $ git push -u origin master To git@github.com:y ...

  9. 【转】【C++】__stdcall、__cdcel和__fastcall三者的区别

    __stdcall.__cdecl和__fastcall是三种函数调用协议,函数调用协议会影响函数参数的入栈方式.栈内数据的清除方式.编译器函数名的修饰规则等.如下图所示,可以在IDE环境中设定所有函 ...

  10. 3d引擎列表

    免费引擎 Agar - 一个高级图形应用程序框架,用于2D和3D游戏. Allegro library - 基于 C/C++ 的游戏引擎,支持图形,声音,输入,游戏时钟,浮点,压缩文件以及GUI. A ...