Size Balanced Tree(SBT)平衡二叉树

定义数据结构

struct SBT
{
    int key,left,right,size;
} tree[N];
key:存储值,left,right:左右子树,size:保持平衡最终要的数据,表示子树的大小

SBT树的性质

定义一个节点x,同时满足下面两个条件
(a)、x.left.size >= max(x.right.right.size, x.right.left.size)
(b)、x.right.size >= max(x.left.left.size, x.left.right.size)
即每棵子树的大小不小于其兄弟子树的大小
image:sbt1.PNG
结点L 和R 分别是结点T 的左右儿子。子树A;B;C;D 分别是结点L 和R 各自的左右子树。
即:R.size >= max(A.size,B.size)
L.size >= max(C.size,D.size)

旋转


左旋伪代码:
Left-Rotate (t)

1     k ← right[t]
2     right[t] ← left[k]
3     left[k] ← t
4     size[k] ← size[t]
5     size[t] ← size[left[t]] + size[right[t]] + 1
6     t ← k
void left_rot(int &x)
{
    int y = tree[x].right;
    tree[x].right = tree[y].left;
    tree[y].left = x;
    tree[y].size = tree[x].size;//转上去的节点数量为先前此处节点的size
    tree[x].size = tree[tree[x].left].size + tree[tree[x].right].size + 1;
    x = y;
}


右旋
Right-Rotate(t)

1     k ← left[t]
2     left[t] ← right[k]
3     right[k] ← t
4     size[k] ← size[t]
5     size[t] ← size[left[t]] + size[right[t]] + 1
6     t ← k
void right_rot(int &x)
{
    int y = tree[x].left;
    tree[x].left = tree[y].right;
    tree[y].right = x;
    tree[y].size = tree[x].size;
    tree[x].size = tree[tree[x].left].size + tree[tree[x].right].size + 1;
    x = y;
}
旋转只需要理解如何维护子树size即可,旋转操作不能改变二叉查找树的基本性质

维护SBT性质(Maintain)

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

第一种情况:x.left.left.size > x.right.size


image:sbt1.PNG
即:insert(T.left,key)后A.size > R.size
1、首先执行Right-Ratote(t),这个操作使上图变成下图;
image:sbt4.PNG



2、在这之后,有时候这棵树还仍然不是一棵SBT,因为 s[C]>s[B] 或者 s[D]>s[B] 也是可能发生的。所以就有必要继续调用Maintain(T)。
3、结点L的右子树有可能被连续调整,因为有可能由于性质的破坏需要再一次运行Maintain(L)。

第二种情况:x.left.right.size > x.right.size
image:sbt5.PNG
在执
  • 11
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值