跳转至

B 树

1 B 树使用场景

二叉树、平衡二叉树适用于存储在计算机内存中较小的文件,统称为 内查找法。若文件很大且存放于外存进行查找时,这些查找方法就不适用了。外查找法都以结点为单位进行查找,这样需要反复地进行内、外存的交换,是很费时的。1970 年,R.Bayer 和 E.Mccreight 提出了一种适用于外查找的平衡多叉树——B 树,磁盘管理系统中的目录管理,以及数据库系统中的索引组织多数都采用 B 树这种数据结构。

2 B 树定义

  • 树的阶:树中结点最大子树个数为 m,则称为 m 阶树
  • 关键字(key):B 树中一个结点可以有多个关键字,此关键字就相当于二叉树结点的值。关键字数量满足关系 [m/2]<=n<=m-1
  • 一棵 m 阶的 B 树,或为空树,或为满足下列特性的 m 叉树:
  • 树中每个结点至多有 m 棵子树
  • 若根结点不是叶子结点,则 至少有两棵子树
  • 除根之外的所有 非终端结点至少有 m/2 棵子树
  • 所有的 叶子结点都出现在同一层次上,并且不带信息,通常称为失败结点(或者叫 NULL 结点,失败结点并不存在,指向这些结点的指针为空。引入失败结点是为了便于分析 B 树的查找性能):
  • 所有的 非终端结点最多有 m-1 个关键字,结点的结构如图 7.21 所示。其中 n 表示结点关键字数量,P 指子结点点指针,K 指关键字。

B树结点结构图 一颗4阶的B树

3 B 树优缺点

特点: 1. B 树的 插入可能会引起结点的分裂,而 删除可能会引起结点的合并。 优点: 2. B 树的高度远远小于 AVL 树和红黑树

4 B 树查询

4.1 算法步骤

将给定值 key 与根结点的各个关键字 Ki,Kj,(1≤j≤m-1) 进行比较,由于该关键字序列是有序的,所以查找时可采用顺序查找,也可采用折半查找。查找时: 1. 若 key=Ki(1≤i≤j),则查找成功; 2. 若 key<K1,则顺着指针 P0 所指向的子树继续向下查找; 3. 若 Ki<keyKj 则顺着指针 Pj 所指向的子树继续向下查找。 如果在自上而下的查找过程中,找到了值为 key 的关键字,则查找成功;如果直到叶子结点也未找到,则查找失败。

5 B 树插入

5.1 插入规则

  1. 每次插入一个关键字 不是在树中添加一个叶子结点,而是首先在 最底层的某个非终端结点中添加一个关键字。(关键字个数区间为 [m/2]<=n<=m-1
  2. 当结点插入关键字后数量 n 满足 [m/2]<=n<=m-1,则插入成功。
  3. 当结点插入关键字后数量 n 不满足 [m/2]<=n<=m-1,则需要在同一层进行结点分裂。

5.2 节点分裂

  1. 以中间关键字为界把结点一分为二,成为两个结点,并把中间关键字向上插入到双亲结点上。
  2. 若双亲结点已满,则采用同样的方法继续分解。
  3. 最坏的情况下,一直分解到树根结点,这时 B- 树高度增加 1。

B树结点分裂

5.3 算法步骤

①在 B 树中查找给定关键字的记录,若查找成功,则插入操作失败;否则将新记录作为空指针 p插人到查找失败的叶子结点的上一层结点(由 q 指向)中。 ②若插入新记录和空指针后,q 指向的结点的关键字个数未超过 m-1,则插入操作成功,否则转入步骤③。 ③以该结点的第 [m/2] 个关键字 K[m/2] 为拆分点,将该结点分成 3 个部分:K[m/2] 左边部分、[Km/2][Km/2] 右边部分。K[m/2] 左边部分仍然保留在原结点中;K[m/2] 右边部分存放在一个新创建的结点(由 p 指向)中;关键字值为 K[m/2] 的记录和指针 p 插入到 q 的双亲结点中。因 q 的双亲结点增加一个新的记录,所以必须对 q 的双亲结点重复②和③的操作,依次类推,直至由 q 指向的结点是根结点,转入步骤④。 ④由于根结点无双亲,则由其分裂产生的两个结点的指针 p 和 q,以及关键字为 K[m/2] 的记录构成一个新的根结点。此时,B 树的高度增加 1。

6 B 树的删除

6.1 删除规则

  1. m 阶 B 树的删除操作是在 B- 树的某个结点中删除指定的关键字及其邻近的一个指针,删除后应该进行调整使该树仍然满足 B 树的定义,也就是要保证每个结点的关键字数目范围为 [m/2]<=n<=m-1
  2. 删除记录后,结点的关键字个数如果小于 [m/2-1],则要进行“合并”结点的操作。
  3. 除了删除记录,还要删除该记录邻近的指针。
  4. 若该结点为最下层的非终端结点,由于其指针均为空,删除后不会影响其他结点,可直接删除;
  5. 若该结点不是最下层的非终端结点,邻近的指针则指向一棵子树,不可直接删除。此时可做如下处理:将要删除记录用其右 (左) 边邻近指针指向的子树中关键字最小(大)的记录(该记录必定在最下层的非终端结点中) 替换。采取这种方法进行处理,无论要删除的记录所在的结点是否为最下层的非终端结点,都可归结为在最下层的非终端结点中删除记录的情况。

6.2 结点合并

6.3 算法步骤