B树操作详解
插入:
普通的插入操作,会导致B树的结构损坏,所以B树是将新添的关键字填加到现有的节点,但是这样有一个问题,就是B树的节点有关键字的数量限制(最多不能超过2t-1个关键字),所以当我们遍历搜索插入位置的时候我们需要顺便将满的节点(孩子数目为t、关键字数目为t-1)分裂,所以在B树的插入操作的核心就是在满节点的分裂上,剩下的就是将关键字插入到子节点中对的位置就可以了。下面我将要讲解如何分裂满节点的。
满节点的分裂
- 若节点为根节点,则该节点从中间分为2个包含t-1个关键字的节点,将中间的关键字提上去新建一个节点作为节点保存,左右两边孩子指针分别指向分裂出来的左右节点。
- 若节点为内部节点或者叶子节点则将该节点从中间分为2个包含t-1个关键字的节点,将中间的关键字提上去添加到父节点,左右两边孩子指针分别指向分裂出来的左右节点,因为是遍历过来的,遍历过程中的分裂确保了父节点不是满节点,所以直接添加到父节点中就可以。
涉及到具体实现可以当节点为根节点时,添加一个空的节点作为根节点,然后走第二部。
删除:
B树的删除操作跟B树的插入操作思路是一样的。都是为防止B树结构被破坏,所以在现有节点内部操作关键字。
删除操作是在现有节点删除一个关键字。但是B树节点的关键字数量有最少限制(n≥t-1)所以当节点的关键字数量为t-1的时候删除一个关键字则会造成少于t-1个,则也会破坏B树的结构,如何解决问题呢,下面将进行阐述。
处理最少关键字节点
因为一下过程是可能让父节点少一个关键字的,所以要保证刚遍历过的节点不会出现为最小关键字数量的情况
在遍历搜索删除时为了处理关键字为t-1个的节点(删除一个关键字后就会破坏B树结构),所以要对要遍历的关键字数量为t-1的节点x进行处理。有两种情况
1、若x的左邻居节点或右邻居节点的关键字数目≥t,则向该邻居节点借一个关键字用。但是B树是有序的,所以不能简单的直接借一个节点直接拿过来,所以要换个方式最终达到相同的效果,即先向父节点借,然后让父节点找邻居节点还。
2、若左右邻居节点关键字都为最小数量t-1,则选取其中一个合并,并将他们两个中间的父节点关键字加入到里面。,所以会导致父节点关键字数目减一,所以我们遍历每个节点都要处理最少关键字节点
删除节点的关键字
当遍历在x节点找到k关键字时
1、若x节点为叶子节点则直接删除即可。
2、若x节点为内部节点。删除关键字后会导致x少一个关键字,所以需要从左右子节点中借一个关键字来让x节点正常,若左右子节点中关键字数目都为最少数目,则将k从父节点中删除,然后k和左右节点合并,然后递归删除k。