数据结构之B-树、B+树

1、B-树

  • 一颗 m 阶的 B-树,或者本身是空树,否则必须满足以下特性:
    • 树中每个结点至多有 m 棵子树;
    • 若根结点不是叶子结点,则至少有两棵子树;
    • 除根之外的所有非终端结点至少有棵子树;
    • 所有的非终端结点中包含下列信息数据:(n,A0,K1,A1,K2,A2,…,Kn,An);
      • n 表示结点中包含的关键字的个数,取值范围是:⌈m/2⌉-1≤ n ≤m-1。Ki (i 从 1 到 n)为关键字,且 Ki < Ki+1 ;Ai 代表指向子树根结点的指针,且指针 Ai-1 所指的子树中所有结点的关键字都小于 Ki,An 所指子树中所有的结点的关键字都大于 Kn。
    • 所有的叶子结点都出现在同一层次,实际上这些结点都不存在,指向这些结点的指针都为 NULL
  • image.png

B-树的查询操作

  • 例如在如图 2 所示的 B-树中查找关键字 47 的过程为:
  1. 从整棵树的根结点开始,由于根结点只有一个关键字 35,且 35 < 47 ,所以如果 47 存在于这棵树中,肯定位于 A1 指针指向的右子树中;
  2. 然后顺着指针找到存有关键字 43 和 78 的结点,由于 43 < 47 < 78,所以如果 47 存在,肯定位于 A1 所指的子树中;
  3. 然后找到存有 47、53 和 64 三个关键字的结点,最终找到 47 ,查找操作结束;

B-树中插入关键字

  • 因为对于 m 阶的 B-树来说,在定义中规定所有的非终端结点(终端结点即叶子结点,其关键字个数为 0)中包含关键字的个数的范围是[⌈m/2⌉-1,m-1],所以在插入新的数据元素时,首先向最底层的某个非终端结点中添加,如果该结点中的关键字个数没有超过 m-1,则直接插入成功,否则还需要继续对该结点进行处理。
  • 在构建 B-树的过程中,假设 p 结点中已经有 m-1 个关键字,当再插入一个关键字之后,此结点分裂为两个结点,如下图所示:image.png
  • 提示:如图 9所示,结点分裂为两个结点的同时,还分裂出来一个关键字 K⌈m/2⌉,存储到其双亲结点中。

B-树中删除关键字

  • 在 B-树种删除关键字时,首先前提是找到该关键字所在结点,在做删除操作的时候分为两种情况,一种情况是删除结点为 B-树的非终端结点(不处在最后一层);另一种情况是删除结点为 B-树最后一层的非终端结点
    • 如果该结点为非终端结点且不处在最后一层,假设用 Ki 表示,则只需要找到指针 Ai 所指子树中最小的一个关键字代替 Ki,同时将该最小的关键字删除即可。
    • 如果该结点为最后一层的非终端结点,有下列 3 种可能:
      • 被删关键字所在结点中的关键字数目不小于⌈m/2⌉,则只需从该结点删除该关键字 Ki 以及相应的指针 Ai 。
      • 被删除关键字所在的结点如果和其相邻的兄弟结点中的关键字数目都正好等于⌈m/2⌉-1,假设其有右兄弟结点,且其右兄弟结点是由双亲结点中的指针 Ai 所指,则需要在删除该关键字的同时,将剩余的关键字和指针连同双亲结点中的 Ki 一起合并到右兄弟结点中。
      • 被删关键字所在结点中的关键字数目等于⌈m/2⌉-1,而与该结点相邻的右兄弟结点(或者左兄弟)结点中的关键字数目大于⌈m/2⌉-1,只需将该兄弟结点中的最小(或者最大)的关键字上移到双亲结点中,然后将双亲结点中小于(或者大于)且紧靠该上移关键字的关键字移动到被删关键字所在的结点中。

2、B+树

  • 一颗 m 阶的 B+树和 m 阶的 B-树的差异在于:
    • 有 n 棵子树的结点中含有 n 个关键字;在 B-树中的每个结点关键字个数 n 的取值范围为⌈m/2⌉ -1≤n≤m-1,而在 B+树中每个结点中关键字个数 n 的取值范围为:⌈m/2⌉≤n≤m
    • 所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
    • 所有的非终端结点(非叶子结点)可以看成是索引部分,结点中仅含有其子树(根结点)中的最大(或最小)关键字。
      • image.png
  • B+树中含有两个头指针,一个指向整棵树的根结点,另一个指向关键字最小的叶子结点。同时所有的叶子结点依据其关键字的大小自小而大顺序链接,所有的叶子结点构成了一个 sqt 指针为头指针的链表。
  • 所有,B+树可以进行两种查找运算:一种是利用 sqt 链表做顺序查找,另一种是从树的根结点开始,进行类似于二分查找的查找方式。

B+树中插入关键字

  • 在B+树中插入关键字时,需要注意以下几点:
    • 插入的操作全部都在叶子结点上进行,且不能破坏关键字自小而大的顺序;
    • 由于 B+树中各结点中存储的关键字的个数有明确的范围,做插入操作可能会出现结点中关键字个数超过阶数的情况,此时需要将该结点进行“分裂”;
  • B+树中做插入关键字的操作,有以下 3 种情况:
    • 若被插入关键字所在的结点,其含有关键字数目小于阶数 M,则直接插入结束;
    • 若被插入关键字所在的结点,其含有关键字数目等于阶数 M,则需要将该结点分裂为两个结点,一个结点包含⌊M/2⌋,另一个结点包含⌈M/2⌉。同时,将⌈M/2⌉的关键字上移至其双亲结点。假设其双亲结点中包含的关键字个数小于 M,则插入操作完成。
    • 在第 2 情况中,如果上移操作导致其双亲结点中关键字个数大于 M,则应继续分裂其双亲结点。

B+树中删除关键字

  • 在 B+树中删除关键字时,有以下几种情况:
  1. 找到存储有该关键字所在的结点时,由于该结点中关键字个数大于⌈M/2⌉,做删除操作不会破坏 B+树,则可以直接删除。
  2. 当删除某结点中最大或者最小的关键字,就会涉及到更改其双亲结点一直到根结点中所有索引值的更改。
  3. 当删除该关键字,导致当前结点中关键字个数小于⌈M/2⌉,若其兄弟结点中含有多余的关键字,可以从兄弟结点中借关键字完成删除操作。
  4. 第 3 种情况中,如果其兄弟结点没有多余的关键字,则需要同其兄弟结点进行合并
  5. 当进行合并时,可能会产生因合并使其双亲结点破坏 B+树的结构,需要依照以上规律处理其双亲结点。
  • 总之,在 B+树中做删除关键字的操作,采取如下的步骤:
    • 删除该关键字,如果不破坏 B+树本身的性质,直接完成操作;
    • 如果删除操作导致其该结点中最大(或最小)值改变,则应相应改动其父结点中的索引值;
    • 在删除关键字后,如果导致其结点中关键字个数不足,有两种方法:一种是向兄弟结点去借,另外一种是同兄弟结点合并。(注意这两种方式有时需要更改其父结点中的索引值。)
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值