数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除

文章目录

    • 索引顺序访问方法ISAM
      • `ISAM方法`
      • `ISMA问题`
    • m叉搜索树
      • 定义
      • m叉搜索树的高度
      • m叉搜索树的搜索
      • m叉搜索树的插入
      • m叉搜索树的删除
    • m阶B-树
      • 定义
      • B-树的高度
      • B-树的搜索
      • B-树的插入
      • B-树的删除
    • B+树
      • 定义
      • B+树的搜索
      • B+树的插入
      • B+树的删除

数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第1张图片

索引顺序访问方法ISAM

  • 之前的数据结构中,我们默认数据都存放在同一存储介质中,如内存。

  • 但在实际应用中,大型字典因为数据量过大一般存储在磁盘中,等到用的时候再从磁盘取出利用内存处理。

  • 在磁盘中存取数据的速度比在内存中处理大概慢几十倍甚至百倍。所以对于存储在磁盘中的数据,存取所需要的数据需要访问磁盘的次数就变成了非常重要的指标。相比之下,将取出的数据在内存中处理耗费的时间可以忽略不计。

ISAM方法

可用的磁盘空间被划分为很多块,块是磁盘空间的最小单位,被用来作为输入和输出。字典元素以升序存储在块中。ISAM方法提供顺序访问和随机访问.

  • 顺序访问
    • 依次输入各个块,在每个块中按升序搜索元素。
    • 如果每个块中包含m个元素,搜索每个元素的磁盘访问次数是1/m.
  • 随机访问
    • 必须维护一个索引表数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第2张图片

      • 索引一般足以驻留内存.

      • 随机访问关键字为k的元素

        • 搜索索引表

        • 关键字为k的元素所属的块从磁盘读入内存

        • 在块中搜索关键字为k的元素

          一次随机访问需要一次磁盘访问

    • 当字典跨越几个磁盘时。元素按升序被分配到各个磁盘以及每个磁盘的不同块中。数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第3张图片

      • 随机访问一个元素:

        • 搜索驻留内存的磁盘索引

        • 在相应磁盘中读入块索引并搜索元素所在的块

        • 从磁盘中读入块,并搜索元素

          一次随机访问需要两次磁盘访问

ISMA问题

当执行插入和删除操作时,会面临很大的问题——块间元素的移动

解决办法:在每个块中预留一些空间

  • 插入少量元素时,不需要块和块之间移动元素
  • 删除后,空间保留

m叉搜索树

定义

m叉搜索树可以是一棵空树,如果非空,它必须满足以下特征:数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第4张图片

  1. 在相应的扩充搜索树中(用外部节点替换空指针),每个内部节点最多可以有m个子女及1~(m-1)个元素(外部节点不含元素和子女)。

  2. 每个含p个元素的节点,有p+1个子女(包括外部节点)

  3. p 个元素的任意节点,设 k 1 , k 2 … , k p k_1 ,k_2 …, k_p k1,k2,kp 是这些元素的关键值。这些元素升序排列。设 c 0 , c 1 , … , c p c_0 , c_1 , …, c_p c0,c1,,cp是该节点的p+1个孩子。

    • c 0 c_0 c0 为根的子树中的元素关键值小于 k 1 k_1 k1

    • c p c_p cp 为根的子树中的元素关键值大于 k p k_p kp

    • c i c_i ci 为根的子树中的元素关键值会大于 k i k_i ki 而小于 k i + 1 k_{i+1} ki+1,其中1≤i≤p。

      仔细对照上图理解性质

m叉搜索树的高度

高度:h(不包括外部节点)

元素数目:n

h ≤ n ≤ m h − 1 h≤n≤m^h-1 hnmh1 l o g m ( n + 1 ) ≤ h ≤ n log_m(n+1)≤h≤n logm(n+1)hn

数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第5张图片

搜索、插入和删除操作需要的磁盘访问次数:O(h)

m叉搜索树的搜索

与二叉搜索树的搜索方法很相似,但注意实际中是从磁盘中取出在内存处理。

数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第6张图片

  • 比如我们寻找上图的元素32
    • 根据内存中索引地址找到根节点所在的磁盘块,把根节点和其中所有的元素及其指针读取到内存中,在内存中搜索节点中的元素。
    • 因为10<32<80,根据根节点的第二个孩子指针继续往下寻找,从磁盘读取节点。
    • 因为30<32<40,继续读取孩子节点,找到元素32,搜索成功。
    • 寻找元素32一共读取三次磁盘
  • 如果寻找元素31
    • 最终会取出外部节点,算法结束,搜索失败(没有相应元素)。

m叉搜索树的插入

数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第7张图片

  • 首先对m叉搜索树进行搜索,寻找是否与插入的节点相同的关键字的节点,如果有则算法失败。
  • 如果没有找到与插入的节点相同的关键字节点
    • 首先判断节点是否可以容纳更多的元素,如果可以,按顺序插入。
    • 如果不可以,插入到下一层的外部节点中,并保持m叉搜索树的性质。

m叉搜索树的删除

删除,分三种情况

  • 删除元素的相邻子树都为空

    例:删除20,84——简单地从节点中删除

    数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第8张图片

    数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第9张图片

  • 删除元素的相邻子树一个不为空

    例:删除5——从不空的相邻子树中找一个元素替换被删除元素

    数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第10张图片

    数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第11张图片

  • 删除元素的相邻子树都不空

    例:删除10——从不空的相邻子树中找一个元素替换被删除元素

    数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第12张图片

    数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第13张图片


m阶B-树

ISAM是一种数组(公式化)描述方法,而公式化描述的缺点就是不适用于频繁的插入和删除操作,难以扩展。

B树便是一种树形描述方法,B树只适用于随机检索,一次搜索访问磁盘的次数最多为树的高度h。可是B树的优势为便于扩展,在插入与删除上的表现要优于ISAM。

定义

m阶B-树(B-Trees of Order m)是一棵m叉搜索树,如果B-树非空,那么相应的扩充树满足下列特征:数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第14张图片

  • 根节点至少有2个孩子。
  • 除了根节点以外,所有内部节点至少有 m / 2 m/2 m/2个孩子。
  • 所有外部节点位于同一层上。

2阶B-树→二阶B-树的所有内部节点都恰好有2个孩子。

  • 2阶B-树是一棵满二叉树(所有外部节点必须在同一层上)

3阶B-树

  • 3阶B-树的内部节点既可以有2个也可以有3个孩子,因此也把三阶B-树称作 2-3树 数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第15张图片

4阶B-树

  • 4阶B-树的内部节点必须有2个、3个或4个孩子,这种树也叫作2-3-4树(或简称2,4树)。

B-树的高度

d = m / 2 d = m/2 d=m/2 ,对于一棵高度为h的m阶B树(外部节点不算元素)。

  • 元素数目n最小: 2 d h − 1 − 1 2d^{h-1}-1 2dh11

  • 元素数目n最大: m h − 1 m^h-1 mh1

  • 数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第16张图片

  • l o g m ( n + 1 ) ≤ h ≤ l o g d ( ( n + 1 ) / 2 ) + 1 log_m{(n+1)}≤h≤log_d{((n+1)/2)+1} logm(n+1)hlogd((n+1)/2)+1

B-树的搜索

与m叉搜索树的搜索算法相同,访问磁盘次数最多为h。

B-树的插入

插入实现思路

  • 插入操作首先执行搜索算法,如果找到相同关键字元素,插入失败,算法结束。
  • 否则找到相应的位置,插入
    • 如果插入后节点中的元素个数不大于m-1,算法结束,插入成功。
    • 如果插入后节点中的元素个数为m从d处开始分裂
      • 节点中第d大的元素作为溢出元素,插入到父节点
      • 节点中分开的两部分分别做溢出元素的“左右子树”
  • 因为溢出节点插入到上一层后,上一层又可能溢出,最坏的情况下需要一直分裂到根节点。

一个裂到根的流程示例

磁盘访问的总次数

假设:B-树的高度:h ,s个节点分裂,磁盘访问次数:h+2s+1

  • 1:回写新的根节点或插入后没有导致分裂的节点
  • 最多:3h+1

如上:Insert(44)

  • 搜索44:3
  • 3个节点被分裂(split):6(每个节点被分裂:2次写操作)
  • 产生一个新的根节点并写回磁盘:1
  • 磁盘访问的总次数: 10

B-树的删除

删除分为三种情况

  • 情况①:在某一节点删除元素后,节点的元素个数仍大于等于d-1, 直接删除元素,算法结束。
  • 情况②:在某一节点删除元素后,节点的元素个数小于d-1,但其最邻近的左兄弟或右兄弟节点的元素个数大于d-1,那么:
    • "薅"一个父节点中的元素
    • 再将兄弟节点中的元素"还"一个给父节点
  • 情况③:在某一节点删除元素后,节点的元素个数小于d-1,并且其最邻近的左兄弟和右兄弟节点的元素个数都等于d-1
  • 我们还是"薅"一个父节点的元素,但拿了之后,孩子节点没有多余的元素可以还给他,并且父节点可容纳的孩子数少了一个。
  • 于是我们将节点与一兄弟节点进行合并,将两个孩子节点组成一个新的孩子节点。
    • 而且父节点的元素被薅了一个之后,父节点的元素数量可能小于d-1,需要继续往上"薅",最坏的情况下需要薅到根节点。

从下图中删除元素10:

数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第17张图片

对应第三种情况

数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第18张图片

空节点继续往上"薅",对应第二种情况

数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第19张图片

一个薅到根的流程实例

数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第20张图片

磁盘访问次数

磁盘访问次数=搜索次数+读取最相邻兄弟次数+修改后节点写回次数

如上delete(44)

  • 搜索 44: 4
  • 读取最相邻的兄弟:3
  • 修改后的节点写回:3 ((35,40),(20,30),(50,80))
  • 磁盘访问的总次数:10

对于高度为h的B-树的删除操作的最坏情况:磁盘访问次数是3h

  • 找到包含被删除元素的节点: h次读访问
  • 获取第2至h层的最相邻兄弟:h-1次读访问
  • 在第3至h层的合并:h-2次写访问
  • 对修改过的根节点和第2层的两个节点:3次写访问。

B+树

定义

B+树是一种常用于文件组织的B-树的变形树。一棵m阶的B+树和B-树的差异在于:

  • 所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字记录的指针
  • 叶子结点的本身依关键字的大小从小到大顺序链接。
  • 所有的非终端结点可以看成是索引部分,结点中仅含有其子树(根结点)中最大(或最小)关键字。
  • 通常在B+树上有两个头指针,一个指向根结点,另一个指向关键字最小的叶子结点。数据结构 | 第十五章:平衡搜索树——B-树 | B-树的搜索、插入、删除_第21张图片

B+树的搜索

  • 可进行两种查找运算
    • 一种是从最小关键字起进行顺序查找
    • 另一种是从根结点开始进行随机查找。
  • 在查找时,若非叶结点上的关键字等于给定值,并不终止,而是继续向下直到叶子结点。因此,在B+树中,不管查找成功与否,每次查找都是走了一条从根到叶子结点的路径

B+树的插入

  • B+树的插入仅在叶子结点上进行,当结点中的关键字个数大于m时要分裂成两个结点,它们所含关键字的个数分别为: ( m + 1 ) / 2 (m+1)/2 (m+1)/2 ( m + 1 ) / 2 (m+1)/2 (m+1)/2
  • 并且它们的双亲结点中应同时包含这两个结点的最大关键字。

B+树的删除

  • B+树的删除仅在叶子结点进行,当叶子结点中的最大关键字被删除时,其在非终端结点中的值可以作为一个"分界关键字"存在。
  • 若因删除而使结点中关键字的个数少于 m / 2 m/2 m/2时,则可能要和该结点的兄弟结点合并,合并过程和B-树类似。

参考博客
插入删除等操作所参考学习的优质博客
推荐网站
一个可以在线演示B-树插入删除的神奇网站

你可能感兴趣的:(数据结构,算法与应用,#,数据结构笔记合集,b树,数据结构,c++,算法)