4阶B树(2-3-4树/TwoFourTree)之插入

B树插入满节点分裂有 两种方法。一种是递归写法,即先往下找到要插入的节点,直接插入。满了就传值到上层进行分裂,一种是迭代写法,在找要插入的节点过程中遇到满节点就分裂,自然当插入的节点满了往上传时其父节点非满,不需要分裂。
下面分别说明:

递归

递归写法中,将包括带插入的值在内的4个值排序,左边两个留在原来的节点,第三个往上,第四个作为新节点,即原来节点的父节点的新的子节点,如图。
《4阶B树(2-3-4树/TwoFourTree)之插入》
《4阶B树(2-3-4树/TwoFourTree)之插入》
基本思想就是如此,加入30节点也是满的,则继续分裂。
在分裂时,情况众多,我的递归写法感觉还存在bug。生成1-100的值,使用shuffle随机打乱再插入。但总会出现少值或者树断了的情况。将所想到的情况描述

首先找到节点,判断其值的数量,等于3则进入分裂函数,待分裂的节点为node,待插入的值为x, 递归时,newnode作为nnode, node作为nnode1。

  • 将node的值与x存入优先队列,并从node删除,记录x插入的位置pos(0-3)。之后插入队列前面两个。第三个取出等待上传,第四个取出存在new node中。
  • 判断插入的位置,原因是如果pos是0,1,则newnode成为node的parent的第pos+1个child,原来的child往右移,这样的话原本child2,3就会多出来(因为此时node只有2个值,所以最多3个儿子),作为newnode的左右儿子。如果是2,则将nnode作为newnode的左儿子,child3作为右儿子。如果是3,则nnode1作为左儿子,nnode作为右儿子
  • 判断完位置后,确定父节点。如果当前节点是根节点,则需要new一个根作为父亲,分裂原本的root,也就是node。如果不是根,则parent=node.parent
  • 判断parent的value数目,如果没满则直接插入,插入方法见第二点的描述,返回pos,满了则要再往上分裂,继续递归。
    《4阶B树(2-3-4树/TwoFourTree)之插入》

迭代

分裂流程:

  • 在找要插入的节点过程中遇到满节点就分裂,自然当插入的节点满了往上传时其父节点非满,不需要分裂。分裂node时先将该节点的child2,child3断开
  • 记录并删除data[1], data[2], data[0]留在原来的节点,data[2]成为newnode作为右儿子
  • 如果node为root,则新增节点作为root,将node作为左儿子。如果node不是root,则选node.parent作为parent。
  • data[1]上升到parent中(因为parent已经分裂过或者本来就没满,所以data[1]可以直接插入,记录插入的位置index。
  • 将parent中index后面的子节点都往右移动,给newnode让出位置。newnode连接到index+1的位置
  • 将child2,3连接到newnode上。

那么迭代插入法的插入过程就是从根节点开始,设currentNode=root,然后循环直到找到x要插入的节点。
循环中,如果currentNode为满的,则分裂。并将currentNode设为x可能在的节点current= getChildSibling(current.parent(), x);(比如x<data[2]&&x>data[1],则currentNode在child2的子树中。)
如果到了叶子节点,则break。如果没满又不是叶子节点,则current = getChildSibling(current, x);
跳出循环后,将x插入currentnode中。

    原文作者:B树
    原文地址: https://blog.csdn.net/BenjaminYoung29/article/details/84782453
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注