B树的删除

def

删除操作是指,根据key删除记录,如果B树中的记录中不存对应key的记录,则删除失败。

基本步骤

  1. 如果当前需要删除的key位于非叶子结点上,则用后继key(这里的后继key均指后继记录的意思)覆盖要删除的key,然后在后继key所在的子支中删除该后继key。此时后继key一定位于叶子结点上,这个过程和二叉搜索树删除结点的方式类似。删除这个记录后执行第2步;
  2. 该结点key个数大于等于Math.ceil(m/2)-1,结束删除操作,否则执行第3步;
  3. 如果兄弟结点key个数大于Math.ceil(m/2)-1,则父结点中的key下移到该结点,兄弟结点中的一个key上移,删除操作结束;

否则,将父结点中的key下移与当前结点及它的兄弟结点中的key合并,形成一个新的结点。原父结点中的key的两个孩子指针就变成了一个孩子指针,指向这个新结点。然后当前结点的指针指向父结点,重复上第2步。

有些结点它可能即有左兄弟,又有右兄弟,那么我们任意选择一个兄弟结点进行操作即可。

演示

下面以5阶B树为例,介绍B树的删除操作,5阶B树中,结点最多有4个key,最少有2个key


a)原始状态

clip_image021


b)在上面的B树中删除21,删除后结点中的关键字个数仍然大于等2,所以删除结束。

clip_image023


c)在上述情况下接着删除27。从上图可知27位于非叶子结点中,所以用27的后继替换它。从图中可以看出,27的后继为28,我们用28替换27,然后在28(原27)的右孩子结点中删除28。删除后的结果如下图所示。

clip_image025

删除后发现,当前叶子结点的记录的个数小于2,而它的兄弟结点中有3个记录(当前结点还有一个右兄弟,选择右兄弟就会出现合并结点的情况,不论选哪一个都行,只是最后B树的形态会不一样而已),我们可以从兄弟结点中借取一个key。所以父结点中的28下移,兄弟结点中的26上移,删除结束。结果如下图所示。

clip_image027


d)在上述情况下接着32,结果如下图。

clip_image029

当删除后,当前结点中只有一个key,而兄弟结点中也仅有2个key。所以只能让父结点中的30下移和这个两个孩子结点中的key合并,成为一个新的结点,当前结点的指针指向父结点。结果如下图所示。

clip_image031

当前结点key的个数满足条件,故删除结束。


e)上述情况下,我们接着删除key为40的记录,删除后结果如下图所示。

clip_image033

同理,当前结点的记录数小于2,兄弟结点中没有多余key,所以父结点中的key下移,和兄弟(这里我们选择左兄弟,选择右兄弟也可以)结点合并,合并后的指向当前结点的指针就指向了父结点。

clip_image035

同理,对于当前结点而言只能继续合并了,最后结果如下所示。

clip_image037

合并后结点当前结点满足条件,删除结束。