SB tree (Size Balanced Tree)

本文详细介绍了SizeBalanced树(SBTree)的概念、定义、初始化、插入和删除操作。SBTree是一种平衡树结构,其特点是每个节点的左右子树大小相差不超过一。文中提供了插入和删除函数的实现,以及与AVL树旋转概念的对比。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载:http://www.clarkok.com/blog/?p=347#more-347

采取网友建议,写一下SB Tree。

============================================================================

所谓SB,并不是傻X,而是Size Balanced的意思的。本人也比较建议使用,因为写起来比较简单。这种树形结构有一个特点,对于每一个节点,它的左右子树大小(可以单纯地理解为节点数量)相等或只相差一。

定义和初始化

type
    point       = ^node;
    node        = record
        l,r     : point;
        x,s     : longint;
    end;

var
    root,null   : point;
    tmp         : point;

procedure init;
begin
    new(null);
    null^.x:=-maxlongint;
    null^.s:=0;
    null^.l:=null;
    null^.r:=null;

    root:=null;
end;

这跟其他几种树结构差不多,多维护一个变量s(size),保存以该节点为根的子树的大小。显然的,空子树的大小为0。

插入

PS. 关于旋转请参照AVL树

插入非常简单,先将节点插到正确的位置,然后递归返回时通过旋转调整树的大小。如图:

对于这棵树,插入1:

插到对应的位置:

旋转之后(这里只旋转5,因为2,3节点都是满足要求的):

我们仍然写成函数:

function add(now:point;x:longint):point;
begin
    if now = null then                               // 找到了叶子节点
        begin
            new(now);
            now^.l:=null;
            now^.r:=null;
            now^.s:=1;
            now^.x:=x;
            exit(now);
        end;
    if now^.x >x then
        begin
            now^.l:=add(now^.l,x);
            inc(now^.s);
            if now^.l^.s > now^.r^.s+1 then          // 需要旋转
                begin
                    now^.s:=now^.r^.s+now^.l^.r^.s+1;
                    now^.l^.s:=now^.s+now^.l^.l^.s+1;
                    exit(TurnLeft(now));
                end;
            exit(now);
        end
    else
        begin
            now^.r:=add(now^.r,x);
            inc(now^.s);
            if now^.r^.s > now^.l^.s+1 then
                begin
                    now^.s:=now^.l^.s+now^.r^.l^.s+1;
                    now^.r^.s:=now^.s+now^.r^.r^.s+1;
                    exit(TurnRight(now));
                end;
            exit(now);
        end;
end;

删除

跟AVL一样的思想,旋转到叶子然后删除,并选Size大的子树旋转。住是什么的也参照AVL吧。

function del(now:point;x:longint):point;
begin
    if now = null then
        exit(null);
    if now^.x = x then
        if now^.l^.s > now^.r^.s then
            begin
                now:=TurnLeft(now);
                now^.r:=del(now^.r,x);
                dec(now^.s);
            end
        else
            begin
                if now^.r = null then
                    begin
                        dispose(now);
                        exit(null);
                    end;
                now:=TurnRight(now);
                now^.l:=del(now^.l,x);
                dec(now^.s);
            end
    else
        if now^.x > x then
            now^.l:=del(now^.l,x)
        else
            now^.r:=del(now^.r,x);
    dec(now^.s);
    exit(now);
end;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值