数据结构—B树

1. 简介

  • 如果数据太多导致内存装不下,则必须把数据结构存放到磁盘上,此时大 O O O 模型不再适用。
  • 磁盘的访问代价相比于 CPU 计算和内存访问来说实在是太高了,因此宁愿执行大量的计算,也要减少磁盘 I/O。
  • 不平衡二叉树在最坏的情况下具有线性的深度,因此如果将其作为一种磁盘数据结构,则最坏情况下仍需进行大量的磁盘 I/O。

2. 约束

一棵 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)所有叶节点都处在树的同一层,也具有 [ ⌈ m / 2 ⌉ − 1 , m − 1 ] [\lceil m/2\rceil -1, m-1] [m/21,m1] 个关键码。
(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 树一个节点的大小能填满一个磁盘块,节点中的“指针”实际上就是孩子节点所在的磁盘块号。

在这里插入图片描述

3. 搜索

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

在最好的情况下,关键码位于根节点中,此时搜索操作的只需执行一次磁盘 I/O;最坏情况下,关键码位于叶节点中,此时需执行的 I/O 操作等于树的高度。通常情况下,可以将 B 树的树根常驻于内存中,此时可以减少一次的磁盘 I/O。

设关键码总数为 N N N,则一棵 m m m 阶 B 树的高度为 log ⁡ m N \log_m N logmN

4. 插入

(1)首先找到应当包含待插入关键码的叶节点;
(2)如果目标叶节点还有空闲的空间,则插入关键码,然后成功返回;
(3)否则,将叶节点分裂成两个节点,并把中间的关键码提升到父节点;
(4)如果父节点也已经满了,则继续分裂父节点,并再次提升中间的关键码,重复此过程,直至完成插入;此过程可能会增长树的高度。

在这里插入图片描述

5. 删除

(1)如果要删除的关键码 A A A 位于内部节点中,则用其后继关键码 B B B(关键码 A A A 右边的指针所指子树中的最小的关键码,一定位于叶节点上)覆盖要删除的关键码,然后删除叶节点中相应的关键码 B B B;如果 A A A 位于叶节点上,则直接删除之;设包含待删除关键码的叶节点为 x x x
(2)如果删除关键码后,叶节点 x x x 中关键码个数大于 ⌈ m / 2 ⌉ − 1 \lceil m/2\rceil -1 m/21,则成功返回,否则继续往下执行;
(3)如果 x x x 的右兄弟(左兄弟)节点中关键码的个数大于 ⌈ m / 2 ⌉ − 1 \lceil m/2\rceil -1 m/21,则将右兄弟(左兄弟)节点中最小(最大)的关键码 C C C 上移到父节点中,然后将父节点中小于(大于)关键码 C C C 且与 C C C 紧邻在一起的关键码下移到叶节点 x x x 中,然后成功返回,否则继续往下执行;
(4)将 x x x 与右兄弟(左兄弟)节点合并,并将父节点中指向该兄弟节点的的指针的左边(右边)一个关键码下移到合并后的节点中;如果此操作导致父节点发生了下溢(关键码个数小于 ⌈ m / 2 ⌉ − 1 \lceil m/2\rceil -1 m/21),则继续此步骤中的合并过程,直至父节点不发生下溢,便可成功返回。

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值