B 树是多路平衡树。一棵 m 阶 B 树需要满足如下性质:
每个节点最多有 m - 1 个关键字
根节点最少有 1 个关键字
除根节点外,每个节点最少有 ceil(m / 2) - 1 个关键字
所有叶子节点出现在同一层
节点的子树数量比关键字数量多 1。每个节点形如:(P0, K0, P1, ..., Pi, Ki, Pi+1, ..., Kn-1, Pn),其中:
接下来分析一棵有 n 个关键字的 m 阶 B 树的最大深度和最小深度:
B 树的深度直接影响插入节点、查找节点、删除节点的时间复杂度。
1,如果树为空,那么创建根节点,然后退出
2.1, 否则,令临时指针 node 指向根节点
2.2,设node 的关键字列表为 keywords、孩子节点列表为 children、keywords 的长度为 length,并执行下面的过程:
查找插入位置 pos
如果 children[pos] 不是根节点,那么令 node = children[pos],然后回到步骤 2.2
否则,在 keywords 中的索引为 pos 的位置之前插入 keyword
3,如果 node 的关键字个数超过 m - 1,则执行下面的流程:
B 树的查找是一个交叉查找的过程,其过程如下:
1,如果树为空,那么查找失败
2.1,否则,令临时指针 node 指向根节点
2.2,执行下面的过程:
设 node 的关键字列表为 keywords、孩子节点列表为 children、keywords 的长度为 length
如果 keyword == keywords[index],那么查找成功,返回 node、index
如果 node 是叶子节点,那么查找失败
否则
1, 找到待删除关键字 (deleted_node, deleted_index)
2,查找“真正”删除的节点和位置 (node, index)
3, 移除 node 中索引为 index 的关键字
4, 如果 node 是根节点
5,如果 node 的关键字个数小于 ceil(m / 2) - 1,那么按照如下的方式进行调整
找到node 的父节点、左兄弟、右兄弟
如果左兄弟非空,且关键字个数大于 ceil(m / 2) - 1,那么从左兄弟借一个关键字,然后退出
如果右兄弟非空,且关键字个数大于 ceil(m / 2) - 1,那么从右兄弟借一个关键字,然后退出
否则,如果有左兄弟,则与父节点、左兄弟进行三方合并;如果没有左兄弟,则与父节点、右兄弟进行三方合并
如果父节点是根节点
否则令 node 等于其父节点,然后回到步骤 5