【数据结构】B树

maple tree是B树的优化形式,为了更好的理解maple tree,这里先对B树做一个铺垫学习。

B树的性质

B树是平衡搜索树的一种,对于一个m阶B树它的性质有:

  • 平衡:所有的叶子节点都在一层
  • 有序:节点内有序,左子树都小于它,右子树都大于它
  • 多路:最多 m-1个元素,根节点最少 1个元素,其余节点最少(m/2上取整 - 1)个元素

而这些性质都是在树的操作上保证的。下面就看看B树的插入和删除操作

插入操作

先找到需要插入的node,此时一定是叶子节点。

插入后,如果节点没有上溢出,则结束。如果上溢出,则进行拆分动作,将多处的元素插入父节点。

再判断父节点。

下面用一张图来观察拆分动作。

假设执行插入后,节点有5个元素,已经上溢出。这时候就要执行拆分,以中间元素B为分割点拆分。

复制代码
                            idx
                      +---+ +---+
                      | A | | C |
                      +---+ +---+
                     |     |     |
                     c0    c1    c2
                           /
                       /
                   /
               /
        +---+ +---+ +---+ +---+ +---+
        | X | | Y | | B | | J | | K |
        +---+ +---+ +---+ +---+ +---+
       |     |     |     |     |     |
       c10   c11   c12   c20   c21   c22

拆分后,B元素上移到父节点,而右半部分作为子树也插入父节点。

复制代码
                            idx
                      +---+ +---+ +---+
                      | A | | B | | C |
                      +---+ +---+ +---+
                     |     |     |     |
                     c0    c1    c'    c2
                           /     \
                       /             \
                   /                     \
               /                             \
        +---+ +---+                       +---+ +---+
        | X | | Y |                       | J | | K |
        +---+ +---+                       +---+ +---+
       |     |     |                     |     |     |
       c10   c11   c12                   c20   c21   c22

删除操作

先找到需要删除的元素,如果该元素不在叶子节点,则找到其后继,并替换。总之确保是在叶子节点上做删除操作。

如果删除后,节点没有下溢出,那么删除操作完成。

此时再判断节点的兄弟,如果兄弟节点元素超过一半,那么就借一个过来。如果兄弟元素也不过,则合并。

如果是合并的,那么就往上走一层,看父节点是否下溢出。

借元素

我们先看看从兄弟节点上借元素的情况。

此时左子树的元素下溢出,我们要做的是把父节点上的元素拿来放到最后,然后把右子树的第一个孩子也拿过来。

然后右子树的第一个元素上移到父节点上。

复制代码
                            idx
                      +---+ +---+ +---+
                      | A | | B | | C |
                      +---+ +---+ +---+
                     |     |     |     |
                     c0    c1    c2    c3
                           /     \
                       /             \
                   /                     \
               /                             \
        +---+ +---+                       +---+ +---+ +---+ +---+
        | X | | Y |                       | J | | K | | L | | M |
        +---+ +---+                       +---+ +---+ +---+ +---+
       |     |     |                     |     |     |     |     |
       c10   c11   c12                   c20   c21   c22   c23   c24

最后的结果是这样。

复制代码
                            idx
                      +---+ +---+ +---+
                      | A | | J | | C |
                      +---+ +---+ +---+
                     |     |     |     |
                     c0    c1    c2    c3
                           /     \
                       /             \
                   /                     \
               /                             \
        +---+ +---+ +---+                 +---+ +---+ +---+
        | X | | Y | | B |                 | K | | L | | M |
        +---+ +---+ +---+                 +---+ +---+ +---+
       |     |     |     |               |     |     |     |
       c10   c11   c12   c20             c21   c22   c23   c24

合并兄弟

合并兄弟的操作实际是拆分操作的反向操作。

此时,左子树已经下溢出,其兄弟也没有足够的元素。

就需要把父节点的元素拉下来放到最后,然后把兄弟也加到后面。

复制代码
                            idx
                      +---+ +---+ +---+
                      | A | | B | | C |
                      +---+ +---+ +---+
                     |     |     |     |
                     c0    c1    c2    c3
                           /     \
                       /             \
                   /                     \
               /                             \
        +---+                             +---+ +---+
        | X |                             | J | | K |
        +---+                             +---+ +---+
       |     |                           |     |     |
       c10   c11                         c20   c21   c22

最后的结果就像这样。

复制代码
                            idx
                      +---+ +---+
                      | A | | C |
                      +---+ +---+
                     |     |     |
                     c0    c1    c3
                           /
                       /
                   /
               /
        +---+ +---+ +---+ +---+
        | X | | B | | J | | K |
        +---+ +---+ +---+ +---+
       |     |     |     |     |
       c10   c11   c20   c21   c22

原文

相关推荐
Darling噜啦啦4 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
小小工匠5 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
玖玥拾5 天前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
Qres8215 天前
算法复键——树状数组
数据结构·算法
牛油果子哥q5 天前
并查集(DSU)超精讲,路径压缩、按秩合并、万能模板、连通性判定、最小生成树与刷题实战全解
数据结构·c++·最小生成树·并查集
凌波粒5 天前
LeetCode--491.递增子序列(回溯算法)
数据结构·算法·leetcode
WL学习笔记5 天前
单项不带头不循环链表
数据结构·链表
小糯米6015 天前
JS 数组
数据结构·算法·排序算法
小欣加油5 天前
leetcode3612 用特殊操作处理字符串I
数据结构·c++·算法·leetcode·职场和发展
凌波粒5 天前
LeetCode--90.子集II(回溯算法)
数据结构·算法·leetcode