B-树

M阶B-树:一棵M阶B-树或者是一棵空树,或者是满足下列特性的M叉树:

 (1)树的根或者是一片树叶,或者其儿子数在2和M之间;

   (2)除根之外的所有非终端结点的儿子数在éM/2ù和M之间;

(3)所有的树叶都在相同的深度上

所有的数据都存储在树叶上。在每一个内部节点上皆含有指向该节点各儿子的指针P1,P1,…Pm和分别代表在子树P2,P3,…Pm中发现的最小关键字的值K1,K2,…Km-1。当然,这些指针可能有些是NULL,而其对应的关键字Ki也是为定义的。对于每一个节点,其子树P1中的所有关键字都小于P2的关键字,如此等等。此处我们还要求在树叶中的关键字个数也在éM/2ù和M之间。

下图中的树是4阶B-树的一个例子。


       4阶B-树更流行的一个称呼是2-3-4树,而3阶B-树叫做2-3树。下面将通过2-3树的特殊情形来描述B-树的操作。现在从下面的2-3树开始


用椭圆画出内部节点(非树叶),每个节点含有两个数据。椭圆中的短横线表示节点的第二个信息,它表明该节点只有两个儿子。树叶用方框画出,框内含有关键字。树叶中的关键字是有序的。为了执行一次Find,我们从根开始,并根据要查找的关键字与存储在节点上的两个(很可能是一个)值之间的关系确定(最多)三个方向中的一个方向。

为了插入(Insert)新关键字X,我们首先按照执行Find的步骤进行。当到达一片树叶时,即找到了插入X的正确位置。例如,为了插入关键字为18的节点,我们可以就把它添加到一片树叶上而不破坏2-3树的性质。插入结果如下图所示:


       

        不过,由于一片树叶只能容纳两个或三个关键字(对2-3树而言),因此上面的做法并不总是可能的。如果现在试图把1插入到树中去,就会发现1所属的节点已经满了。将这个心的关键字放入该节点使得它有了四个关键字,这是不允许的。解决的办法是,构造两个节点,每个节点有两个关键字,同时调整它们的父节点的信息,如下图:


然而,这个想法也不是总能行得通,当尝试将19插入到当前的树中时就会看出问题。如果构造两个节点,每个节点有两个关键字,那么得到下列的树:


        这个树的一个内部节点有了四个儿子,这不符合2-3树的要求。解决方法很简单,只要将这个节点分成两个节点,每个节点两个儿子即可。当然,这个节点本身可能就是三个儿子节点知悉,而这样分裂该节点将给它的父亲带来一个新问题(该父节点将会有四个儿子),但是,我们可以在通向根的路径上一直这么分下去,直到或者到达根节点,或者找到一个节点,这个节点只有两个儿子。插入19后,得到的树如下:



       如果现在插入关键字为28的一个元素,那么就会出现一片具有四个儿子的树叶,它可以分成两个树叶,每叶两个儿子,如下图所示:


这样又产生一个具有四个儿子的内部节点,此时它被分成两个儿子节点。我们这里做的就是把根节点分成两个节点,这时,我们得到一个特殊情况,通过创建一个新的根节点,我们可以结束对28的插入。这时2-3树增加高度的唯一方法。还要注意,当插入一个关键字的时候,只有在访问路径上的那些内部节点才有可能发生变化。


        对于一个节点的儿子太多的情况还有一些其他的处理办法,而刚才描述的方法恐怕为最简单的情况。当试图将第四个关键字添加到一片树叶上的时候,我们可以首先查找只有两个关键字的兄弟,而不是把这个节点分裂成两个。例如,为把70添加到上面的树中,我们可以把58挪到包含有41和52的树叶中,再把70与59和61放到一起,并调整一些内部节点中的各项。这个策略也可以用到内部节点上并尽量使更多的节点具有足够的关键字。这种方式编程相对而言更复杂,但是浪费的空间更少。

我们可以通过查找要被删除的关键字并将其去除而完成删除操作。如果这个关键字是一个节点仅由的两个关键字中的一个,那么将它除去后就只剩一个关键字了。此时我们可以通过将这个节点与它的一个兄弟合并起来进行调整,如果这个兄弟已经有三个关键字,那么我们可以从中取出一个使得两个节点各有两个关键字。如果这个兄弟只有两个关键字,那么我们就将这两个节点合并成一个具有3个关键字的节点。现在这个节点的父亲则失去一个儿子,因此,我们还要向上检查直到顶部。如果根节点失去它的第二个儿子,那么这个根也要删除,而树则减少一层。当我们合并节点的时候,必须要记住更新保存在这些内部节点上的信息。

M阶B-树的深度最多是。在路径上的每个节点,我们执行O(logM)时间的工作量以确定选择哪个分支(折半查找),但是Insert和Delete可能需要O(M)的工作量来调整该节点上的所有信息。因此,对于每个Insert和Delete运算,最坏情形的运行时间为,,不过执行一次Find操作只花费O(logM)时间,经验指出,从运行时间考虑,M的最好选择是M = 3或M=4。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值