数据结构——B树、B+树、B*树

目录

    • (一)B树(B-树)
      • 1、二叉搜索树
      • 2、B树的基本概念
      • 3、m阶B树的性质
      • 4、B树和二叉树的操作比较
    • (二)B+树
      • 1、B+树的基本概念
      • 2、B+树的特征
      • 3、B+的优势
    • (三)B*树
      • 1、B*树的基本概念
      • 2、B*树特点

(一)B树(B-树)

1、二叉搜索树

  二叉搜索树有如下特点:

  • 所有非叶子结点至多拥有两个孩子(Left和Right)
  • 所有结点存储一个关键字
  • 非叶子节点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树
      二叉树的搜索,从根节点开始若查询的关键字与节点关键字相等则命中;否则若关键字比结点关键字小则进入左孩子;如果比结点关键字大,就进入右孩子;若左孩子或有孩子的指针为空,则报告未找到该关键字。

2、B树的基本概念

B树(一种多路搜索树,不一定是二叉)的出现是因为磁盘 IO ,IO操作的效率很低,在大量数据存储中(一般用于数据库索引,查找效率较高),查询时我们不能一下将所有数据都加载到内存中,只能逐一加载磁盘页,每个磁盘页对应树的结点。造成大量磁盘 IO 操作(最坏情况下为树的高度),平衡二叉树由于树的深度过大造成磁盘 IO读写频繁所耗费时间长,导致效率低
      &数据结构——B树、B+树、B*树_第1张图片

  磁盘 IO 与预读
emsp; 磁盘读取以靠机械运动,分为寻道时间、旋转延迟、传输时间三个部分,这三个部分耗时相加为一次磁盘 IO 的时间,大概9ms。成本是访问内存的十万倍左右;正是由于磁盘 IO 非常昂贵的操作,计算机操作系统对此进行优化:预读;每次 IO 时,不仅把当前磁盘地址的数据加载到内存,同时将相邻数据加载到内存缓冲区中,因局部预读原理说明:当访问一个地址数据是,与其相邻的数据也会被很快访问到。每次磁盘 IO 读取的数据我们称之为一页(page)。一页的大小与操作系统有关,一般为4k或8k,读一页内数据的时候,实际上发生了一次磁盘IO。

而在二叉树的查找过程中最坏情况下的磁盘IO的次数与树的高度有关,因此我们要减少磁盘IO则需压缩树的高度,让”瘦高“的二叉树变为”矮胖“的B树。

3、m阶B树的性质

  • 每个结点最多拥有m个子树
  • 根节点至少有两个子树
  • 中间结点至少拥有m/2棵子树(除根节点和叶子结点)
  • 所有叶子节点都在同一层、每个结点最多可有 m-1 个关键字且以升序排列

4、B树和二叉树的操作比较

  查找操作:在少量数据查找过程中B树比对次数和 IO 的次数与二叉树差不了多少,但比对是在内存中完成不涉及到磁盘 IO 耗时可忽略不计,且B树一个结点中可存放多个关键字,相同数量的关键字在B树中的结点远少于二叉树结点,相差结点数量等同于磁盘IO次数,数据到达一定规模后性能上会有明显差异。
  在插入和删除操作中会导致B树的结点发生裂变,因为这样的操作会让B树始终保持多路平衡,这也是B树自身的一个优势:自平衡,B树主要应用于文件系统以及部分数据库索引,入MongoDB,大部分关系型数据库索引使用B+实现。

  巨人的肩膀:http://m.elecfans.com/article/662237.html

(二)B+树

1、B+树的基本概念

  B+树是应文件系统所需而出的一种B-树的变型树,通常用于数据库和操作系统的文件系统中,B+树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度,B+树元素自底向上插入。

2、B+树的特征

  • 有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每个元素不保存数据,只用来索引,所有数据都保存在叶子节点。
  • 所有的叶子结点中包含了全部元素的信息,及指向含这些元素记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
    数据结构——B树、B+树、B*树_第2张图片
  • 所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。
    数据结构——B树、B+树、B*树_第3张图片

3、B+的优势

卫星数据(指索引元素所指向的数据记录)的位置不同,在B树中无论中间结点还是叶子节点都带有卫星数据
数据结构——B树、B+树、B*树_第4张图片
  在B+树种,只有叶子节点带有卫星数据,其余仅仅带有索引没有数据关联:
数据结构——B树、B+树、B*树_第5张图片
  在数据库的聚集索引(Clustered Index)中,叶子节点直接包含卫星数据。在非聚集索引(NonClustered Index)中,叶子节点带有指向卫星数据的指针。
查询性能
  B+树会自顶向下逐层查找结点,最终找到匹配的叶子节点,因为G+树的中间结点没有卫星数据所以同样大小磁盘页可容纳更多结点元素,使得IO次数少,同样数据量的情况下B+树比B树更”矮胖“,其次B+树的查询需最终查到叶子节点B树只要找到匹配元素,无论处于中间结点还是叶子结点,因此B树的查找性能不稳定(有最好情况和最坏情况之分)而B+树每一次查找都是稳定的
范围查询
B树的范围查询要依靠中序遍历,假如要查找(3,11)的数据过程如下:
数据结构——B树、B+树、B*树_第6张图片
B+树所有叶子节点形成有序链表,便于范围查询,B+树的范围查询:
数据结构——B树、B+树、B*树_第7张图片
B+树支持range-query(区间查询)非常方便,而B树不支持。这是数据库选用B+树的最主要原因。
巨人的肩膀:https://blog.csdn.net/qq_26222859/article/details/80631121

(三)B*树

1、B*树的基本概念

  B*树是B+树的变体,在B+树的中间结点再增加指向兄弟的指针。
数据结构——B树、B+树、B*树_第8张图片

2、B*树特点

  B+树的分裂:当一个结点满时,分配一个新的结点,并将原结点中1/2的数据复制到新结点,最后在父结点中增加新结点的指针;B+树的分裂只影响原结点和父结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针;
  B树的分裂:当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字(因为兄弟结点的关键字范围改变了);如果兄弟也满了,则在原结点与兄弟结点之间增加新结点,并各复制1/3的数据到新结点,最后在父结点增加新结点的指针;所以,B树分配新结点的概率比B+树要低,空间使用率更高;
  B*树定义了非叶子结点关键字个数至少为(2/3)*M,即块的最低使用率为2/3(B+树为1/2)。所以,B *树分配新结点的概率比B+树要低,空间使用率更高;

巨人的肩膀:https://zhuanlan.zhihu.com/p/98021010

你可能感兴趣的:(数据结构,数据结构,二叉树)