Tree 在b+中拆分节点;树

Tree 在b+中拆分节点;树,tree,b-tree,multiway-tree,Tree,B Tree,Multiway Tree,我试图弄清楚当出现节点溢出时会发生什么。 信息: 在我的b+树中,每个块有4个指针和3个数据段。 问题: 我知道当出现溢出时,我们会分成2个节点,每个节点有2个 钥匙, 并将父节点插入中间值,而不删除子节点(与b树中不同) 然而,我陷入了这样的境地: |21|30|50| |10|20|-| |21|22|25| |30|40|-| |50|60|80| 我想插入钥匙23 首先我把| 21

我试图弄清楚当出现节点溢出时会发生什么。 信息: 在我的b+树中,每个块有4个指针和3个数据段。 问题: 我知道当出现溢出时,我们会分成2个节点,每个节点有2个 钥匙, 并将父节点插入中间值,而不删除子节点(与b树中不同)

然而,我陷入了这样的境地:

                                |21|30|50|

           |10|20|-|      |21|22|25|  |30|40|-| |50|60|80|  
我想插入钥匙23 首先我把| 21 | 22 | 25 |分为| 21 | 22 |-|和| 23 | 25 |-| 现在,我需要将键23插入到导致另一次分裂的父| 21 | 30 | 50 |女巫。 |21 | 23 |-和| 30 | 50|-| 但是30之前的指针指向哪里呢? 这个指针和23后面的指针是否都指向| 23 | 25|-| ?

插入23时:

  • 正如你所说,21 | 22 |-|和| 23 | 25 |-|是创造出来的
  • 这两个节点需要一个父节点
  • 在根节点中创建父节点:| 21 | 23 | 30 | 50 |
  • 根现在有太多的元素
  • 将根分成两个节点| 21 | 23 |-和| 30 | 50|-
  • 为2个新节点(恰好是树的新根)添加一个新父节点

基本上,该插入将使树的深度增加1

您必须了解发生了什么,这是因为您使用的表示模型不正确。您应该有一个与指针关联的数据值,以及该数据值是指针引用的子树中最小值的不变量

因此,在插入之前,应该这样表示b树节点

                         10|21|30|50|                       <--- root node

         10|20|    21|22|25|     30|40|       50|60|80|     <--- leaf nodes

10 | 21 | 30 | 50 |根据我所学的内容,最后一个节点的一个节点小于n/2是可以的。因此,在您的示例中,顶部节点将变成:

             |23|
         /        \
    |21|22|-|       |25|-|-|
我认为这有点道理。如果你仔细想想,你有5个离开节点,所以你需要5个来自上层的指针。这种安排是唯一的方式,这样你可以有5个指针,所有其他组合要么溢出节点,要么创建额外的指针


如果节点是| 21 | 22 |-|和| 23 | 25 |-|,则根节点将是| 23 |-|-|。那么,右节点中有23是没有意义的,因为右节点中的任何值都必须等于或大于23

以下是应该如何处理指针。这是插入前的B+树。(一些填充用于使指针更容易看到)

插入23后,将有2个节点。重要的是要知道,左分割应该始终是同一个实例,右分割应该是一个新节点。这将使指针的处理更加容易

所以分裂应该是这样的

  old          fresh 
[21|22|-] => [23|25|-]
由于左节点是同一个实例,所以根节点上的键
21
具有正确的右指针。下面是节点在拆分根之前和拆分叶之后的样子。我们正在这个过程中

                [21                             30           50]
               /   \                              \            \
       [10|20|-] => [21|22|-] => [23|25|-] => [30|40|-] => [50|60|80]  
只有键为
23
的新项应添加到根目录中的
21
旁边。因为根目录没有空间,所以它也将被拆分中键为23(右拆分的第一项)

因为根是拆分的,所以我们必须将中间键添加到左拆分或右拆分中,并找到一个新的中间键进行升级。请注意右拆分处的空指针。因为该节点是新的,所以必须尽快初始化它

(根从右侧拆分,这意味着在项目数量奇数的情况下,右侧节点中的项目较少。但通常情况下,拆分方式并不重要。)

我们的中间键是23。那么让我们加上23

                [21            23             30]          [ 50 ]
               /   \             \              \          *    \
       [10|20|-] => [21|22|-] => [23|25|-] => [30|40|-] => [50|60|80]  
好!!如果这里没有分裂,我们的插入现在就完成了。但既然在这个层面上存在分歧,我们就必须找到新的中间键来推动。另外,不要忘记新节点的空指针

(在拆分叶的情况下,必须在叶上保留键值并提升中间键的副本,但在拆分内部节点的情况下,可以安全地向上移动和提升键。)

这里新的中间键是30。让我们从左节点弹出它

 30
   \
[30|40|-]
(如何选择中间键很重要。始终从底部拆分中获取中间键的节点应为新的中间键删除一项。如果该节点是左节点,则从中删除最后一项,否则删除第一项。)

请注意,30不在任何拆分内。这是我们必须处理的中间关键始终将中键的右节点置于新节点的左侧。

                [21            23]       30            [50]
               /   \             \         *          /    \
       [10|20|-] => [21|22|-] => [23|25|-] => [30|40|-] => [50|60|80]  
然后中键的右指针将指向右拆分上的新节点。最后提升中间键,创建具有左分割左、右分割右和中间键键的新根

                                   [       30        ]
                                  /                   \
                [21            23]                     [50]
               /   \             \                    /    \
       [10|20|-] => [21|22|-] => [23|25|-] => [30|40|-] => [50|60|80]
恭喜你!您已完成插入。在纸上看起来可能很简单,但我不得不承认在编写代码时有点困难



有两种方法可以表示内存中的这些
关键节点
项。我的方法是每个
键节点
项都有带键的右指针。因此,每个内部节点都将具有
关键节点的数组。这样,键和节点指针始终保持在一起。最左边的子节点由一个单独的左指针处理,该指针保留在每个内部节点上,并且从不为空(在完成操作之后)。

在B+树中,叶节点和非叶节点具有不同的结构。因此,它们的溢出机制也不同。对于叶节点溢出,您所说的是正确的(这样做时不会从子节点中删除父密钥)。但当非叶节点溢出并被拆分时,子节点不保留父键(父键从子节点中删除)。

thnx快速回答,但问题是:前面提到的指针会发生什么情况。可能是两个指针指向同一个节点吗?有人回答说,指向23键的指针将指向新创建的节点| 30 | 50 |-|。出于某种原因,它被删除了,这对非叶节点是真的吗???我相信你的模型中有错误。第一个表示有4个值,这意味着f中存在5个子节点
                [21            23             30]          [ 50 ]
               /   \             \              \          *    \
       [10|20|-] => [21|22|-] => [23|25|-] => [30|40|-] => [50|60|80]  
 30
   \
[30|40|-]
                [21            23]            30           [ 50 ]
               /   \             \              \          *    \
       [10|20|-] => [21|22|-] => [23|25|-] => [30|40|-] => [50|60|80]  
                [21            23]       30            [50]
               /   \             \         *          /    \
       [10|20|-] => [21|22|-] => [23|25|-] => [30|40|-] => [50|60|80]  
                                   [       30        ]
                                  /                   \
                [21            23]                     [50]
               /   \             \                    /    \
       [10|20|-] => [21|22|-] => [23|25|-] => [30|40|-] => [50|60|80]