Algorithm btree插入的一个特殊问题

Algorithm btree插入的一个特殊问题,algorithm,insertion,b-tree,Algorithm,Insertion,B Tree,我一直在玩非常酷的btree小程序。我很难理解一种特殊的行为。看看这个起始状态: 这个特定的状态是通过插入以下序列来实现的:10、15、30、16、70、1、9、27、45、50、55 我的问题是当我在序列65中插入下一个值时,[45,]节点会发生什么 [55,70]节点将被65拆分,作为中间值,65将返回,然后拆分[30,50]节点。我的问题是:为什么[45,]节点最终成为[30,]节点的子节点?它的父节点最初有3个子节点,最左侧和最右侧成为新的分离节点。45介于这些值之间,似乎它也可以在

我一直在玩非常酷的btree小程序。我很难理解一种特殊的行为。看看这个起始状态:

这个特定的状态是通过插入以下序列来实现的:10、15、30、16、70、1、9、27、45、50、55

我的问题是当我在序列65中插入下一个值时,[45,]节点会发生什么


[55,70]节点将被65拆分,作为中间值,65将返回,然后拆分[30,50]节点。我的问题是:为什么[45,]节点最终成为[30,]节点的子节点?它的父节点最初有3个子节点,最左侧和最右侧成为新的分离节点。45介于这些值之间,似乎它也可以在[65,]节点下结束。。。为什么?

在第二个图中,45节点是65节点的子节点是没有意义的,因为最右边的分支的值大于50(基于根节点最右边的值)-因此45必须进入中间分支的某个位置。

每个节点始终有n+1个子节点,其中n是该节点中的键数

在拆分之前,[30,50]节点有两个键和三个子节点,正如预期的那样。拆分后,将得到一个[30,-]节点和一个[65,-]节点(并将50向上推一级)

在下一级,您有(以前存在的)[16,27]和[45,-],以及新拆分的[55,-]和[70,-]节点

您有两个父节点和四个子节点。每个父项必须有两个子项,因为它只有一个键。因此,根据排序规则,[45,-]必须是[30,-]的孩子,否则(1)[30,-]就不会有足够的孩子,(2)[65,-]就会有太多的孩子。[编辑-对于一个节点来说,数量不是太多,但是分割应该是平衡的]


Will A也是正确的。这是在分割中间层节点时选择向上推50键的结果,但这并不是一个真正的选择。拆分为产生[-,-]和[50,65]向上推30,或[30,50]和[-,-]向上推65,将违反每个节点必须至少满一半的规则。

一张图片抵得上千言万语;一部动画价值100万美元:

这里需要注意的关键是,当中心节点50被拉起时,它必须扔掉它的右子节点,因为它太低了。然而,65岁需要一个新的左撇子,所以50岁的人把45岁交给65岁的人。50现在需要一个新的右子节点,并且包含65的节点需要子节点化,因此它将替换新形成的65

下面是B-树插入规则的图示(其中最大节点大小为4项,5个子节点):


xr
将不存在,并且无论您是否要插入叶子(您首先要做的)。但是,如果必须将节点一分为二,则新的
x
是您提取的中心项,而新的
xr
x

的正确子项,因为所使用的特定算法对我们来说是不透明的,它只提供黑盒测试。将[69,66]添加到最后一棵树对我来说是违反直觉的。。。我不知道我怎么能说得更具体。是的,我同意。。。当我用手做的时候,我把它放在了正确的位置。问题是“毫无意义”很难编码!到目前为止,其他一切都是简单的规则(分割完整节点、向上分割等)……你有没有研究过B树插入规则?我建议研究一些B-树规则的描述,而不是从applet派生逻辑。@dicroce-基本事实是,B-树非常灵活。对于较大的节点,如果希望通过在相邻同级节点之间重新分配密钥来延迟节点拆分和节点合并,则情况会变得更糟,这也意味着两个同级节点之间的父节点中的密钥也将发生更改。我发现更多地考虑所有项目的有序数组是有帮助的,用括号来分隔节点,例如[[9]15[30]50[65]](示例后的前两层)-但仅在一定程度上。@diocre-B+树更容易。所有项目都位于叶节点中,它们都位于同一深度。分支节点仅保存“子树摘要”——例如标准的“子树中的最低键”,以支持基于键的搜索。叶节点通常形成一个列表,因此您不必接触分支节点即可进行顺序访问。拆分、合并和重新分发会更容易一些,因为项目都在叶节点中-通过分支节点向上传播键和其他摘要更新相对简单。当然分支节点仍然会进行拆分/合并等操作。嗯,显然,你的动画值69个单词左右;P+1,回答得好哇,你真的为我的案子做了动画?我希望我能不止一次投票@BaconBits:我托管的服务器不再存在。当我换衣服的时候,我得把这些照片挖出来。谢谢你(再次)提醒我。