数据结构—B+树

1. 约束

B+ 树的约束与 B 树类似,一棵 m m m 阶 B+ 树具有如下特点:

(1)根节点要么是一个叶节点,要么至少具有两个孩子节点;
(2)除根节点以外,每个内部节点都具有 [ ⌈ m / 2 ⌉ , m ] [\lceil m/2\rceil, m] [m/2,m] 个孩子节点,因此具有 [ ⌈ m / 2 ⌉ − 1 , m − 1 ] [\lceil m/2\rceil -1, m-1] [m/21,m1] 个关键码;(有些定义中,要求关键码个数与指针个数相同)
(3)所有叶节点都处在树的同一层;
(4)每个节点都会按序存储关键码,介于关键码 k e y 1 key1 key1 k e y 2 key2 key2 之间的指针所指孩子节点所存储的关键码的范围为 [ k e y 1 , k e y 2 ) [key1, key2) [key1,key2)

与 B 树不同的地方

(1)B+ 树的内部节点只存储关键码,实际记录只存在于叶节点中;如果将 B+ 树作为纯粹的索引实现,叶节点存储关键码及指向相应记录的指针,而实际记录存储在单独的磁盘文件中。
(2)B+ 树的叶节点一般会链接起来,形成一个双链表,如此通过访问链表中的所有叶节点便可以遍历所有的记录,因此适合于范围查询。
(3)B+ 树叶节点存储的记录数可能多于或少于 m m m,只要叶节点至少达到半满即可。
(4)B+ 树的搜索过程必须一直往下直至达到相应的叶节点才可,因为只有叶节点才存储实际的记录。
(5)因为 B+ 树的内部节点只存储关键码而不存储记录,所以其内部节点可以存储更多的关键码,即拥有更多的分支(子树),所以,存储相同数量的关键码时,B+ 树会比 B 树更加“矮胖”。

通常情况下,要使 B+ 树一个节点的大小能填满一个磁盘块,节点中的“指针”实际上就是孩子节点所在的磁盘块号。

2. 搜索

(1)从根节点开始;
(2)在当前节点中对关键码进行二分搜索,然后沿着相应的分支继续往下,重复此步骤,直至到达叶节点;
(3)如果当前节点是叶节点且没有找到目标,则失败返回;否则,返回相应的记录。

3. 插入

设叶节点包含的记录数的范围为 [ ⌈ L / 2 ⌉ , L ] [\lceil L/2 \rceil, L] [L/2,L]

(1)首先找到应当包含待插入关键码的叶节点 x x x
(2)如果目标叶节点还有空闲的空间(记录数少于 L L L),则插入关键码,然后成功返回,否则继续往下执行;
(3)如果目标叶节点已经满了,则在插入关键码之后,将其等分为两个叶节点 x 1 , x 2 x1, x2 x1,x2,然后将叶节点 x 2 x2 x2 中最小的那个关键码的一个副本提升到父节点 y y y 中,如果父节点仍有空闲的空间(关键码个数少于 m − 1 m-1 m1),则成功返回,否则继续往下执行;
(4)将父节点 y y y 分裂为两个节点 y 1 , y 2 y1,y2 y1,y2,其中 y 1 y1 y1 包含前 ⌊ m / 2 ⌋ \lfloor m/2\rfloor m/2 个关键码, y 2 y2 y2 包含后 m − ⌊ m / 2 ⌋ − 1 m-\lfloor m/2\rfloor-1 mm/21 个关键码,然后将第 ⌈ m / 2 ⌉ \lceil m/2\rceil m/2 个关键码提升至 y y y 的父节点 z z z,如果 z z z 仍有空闲的空间,则成功返回,否则继续执行此步骤。

在这里插入图片描述

4. 删除

(1)首先找到包含待删除关键码的叶节点 x x x,然后从中删除指定的关键码,如果删除后, x x x 仍然达到半满,则成功返回,否则继续往下执行;
(2)若 x x x 的右(左)兄弟节点 y y y 包含的记录数大于 ⌈ L / 2 ⌉ \lceil L/2 \rceil L/2,则将 y y y 中最小(最大)的一个关键码及相应的记录移到 x x x 中,然后使用 y y y x x x)中最小的关键码替换父节点中处于 x , y x,y x,y 之间的那个关键码,最后成功返回;否则继续往下执行;
(3)如果 x x x 的左右兄弟节点都没有足够的关键码可借,则将 x x x 及其兄弟节点 y y y 合并为一个节点,并删除父节点 z z z 中处于 x , y x,y x,y 之间的那个关键码,若父节点 z z z 没有发生下溢,则操作成功返回,否则继续往下执行;
(4)若节点 z z z 的右(左)兄弟节点 w w w 包含有富余的关键码,则将节点 z z z 的父节点中处于 z , w z,w z,w 之间的那个关键码 A A A 下移到节点 z z z 中,然后将 w w w 中最小(最大)的那个关键码上移到父节点并替换 A A A,然后成功返回,否则继续往下执行;
(5)若节点 z z z 的左右兄弟 w w w 皆不富余,则将节点 z , w z,w z,w 合并为一个节点,然后将父节点中介于 z , w z,w z,w 之间的那个关键码 A A A 下移到合并后的节点中;如果此操作导致父节点也发生了下溢,则继续回到步骤(4),否则成功返回。

在这里插入图片描述
图示来自 http://www.cnblogs.com/nullzx/ 。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值