(58)王道数据结构-B树

原文地址:B树

基本概念

B树(Balance Tree),它是专门为磁盘数据读取设计的一种度为 m 的查找树(多用于数据库)它同样是一棵平衡树,但是不仅限于二叉。得益于B树这种结点少,高度平衡且有序的性质,而硬盘IO速冻远低于内存,我们希望能够花费尽可能少的时间找到我们想要的数据,减少IO次数,B树就非常适合在硬盘上的保存数据,它的查找效率是非常高的。

基本规则

1.树中每个结点最多含有m个孩子(m >= 2)比如上面就是m为4的4阶B树,最多有4个孩子

2.除根结点和叶子结点外,其它每个结点至少有⌈m/2⌉个孩子,同理键值数量至少有⌈m/2⌉-1个

3.若根结点不是叶子结点,则至少有2个孩子

4.所有叶子结点都出现在同一层

5.一个结点的包含多种信息(P0,K1,P1,K2,…,Kn,Pn),其中P为指向子树的指针,K为键值(关键字)

  • Ki (i=1…n)为键值,也就是每个结点保存的值,且键值按顺序升序排序K(i-1)< Ki

  • Pi为指向子树的指针,且指针Pi指向的子树中所有结点的键值均小于Ki,但都大于K(i-1)

  • 键值的个数n必须满足: ⌈m/2⌉-1 <= n <= m-1

在线动画网站:https://www.cs.usfca.edu/~galles/visualization/BTree.html

操作步骤

例子中用的是度为3的B树

插入操作

第一步:
树中节点:1
插入1之后,只有一个结点

第二步:
树中节点:1,2
满足规则:如果该节点上的元素数未满,则将新元素插入到该节点,并保持节点中元素的顺序

第三步:

之后插入一个3进去,但是此时因为3,那么键值最多只能有两个,肯定是装不下的,此时满足以下规则

  • 如果该节点上的元素已满,则需要将该节点平均地分裂成两个节点
  • 小于中位数的元素作为左子树划分出去,大于中位数的元素作为右子树划分
  • 分割值此时上升到父节点中,如果没有父节点,那么就创建一个新的

第四步:

需要注意的是,插入按照小的走左边,大的走右边的原则

第五步:

1.首先3、4、5三个都分开,其中4作为分割值
2.3、5变成两个独立的数,此时4上升到父节点,所以到上面去了
3.3、5出现在4的左右两边
4.这里不是向下划分,需要满足所有叶子结点都出现同一层

第六步:

继续插入6、7

第七步:

按照之前的操作,对右下角进行分裂,但新的分割结值上升之后最上面的结点挤爆

最后一步:

在2、4、6中寻找一个新的分割值,分裂后将其上升到新的父节点中

删除操作

以一棵5阶B树为例

删除’16’

删除后,依旧满足B树的性质,所以无需其他操作

删除’15’

1.删除后,节点中只有14,不满足B树的性质

2.除了根结点和叶子结点外,其他结点至少有[m/2]个孩子,同理键值数量至少有[m/2]-1个,现在只有一个是不行的

3.需要向兄弟借一个(只能找左右两边的兄弟)

删除’17’

删除17后,兄弟节点已经没有办法借元素了。只能合并兄弟节点和与分割键

合并后存在:
1.父节点只有一个元素

2.兄弟节点也无法借

3.只能继续合并


合并后的树

删除’4’

会导致失去分割值,需要继续寻找分割值,选取左边最大的作为分割值


1.左边结点不满足性质,元素数量低于限制
2.找兄弟借,兄弟无法借
3.只能合并兄弟


合并完成,整个变换过程中,这颗B树所有子树的高度是一直维持在一个稳定状态的,查找效率可以保持

删除总结

●若删除的是叶子结点的中元素:

  • 正常情况下直接删除。

  • 如果删除后,键值数小于最小值,那么需要找兄弟借一个。

  • 要是没得借了,直接跟兄弟结点、对应的分割值合并。

●若删除的是某个根结点中的元素:

  • 一般情况会删掉一个分割值,删掉后需要重新从左右子树中找一个新分割值的拿上来。

  • 要是拿上来之后左右子树中出现键值数小于最小值的情况,那么就只能合并了。

●上述两个操作执行完后,还要继续往上看上面的结点是否依然满足性质,否则继续处理,直到稳定。


(58)王道数据结构-B树
https://www.eldpepar.com/iecore/6253/
作者
EldPepar
发布于
2022年8月22日
许可协议