详解多路查找树(2-3树、2-3-4树、B树、B+树)以及python实现相关操作

多路查找树

  • 引言
  • 1、概述
  • 2、2-3树
    • 2.1 定义
    • 2.2 插入操作
    • 2.3 删除操作
  • 3、2-3-4 树
  • 4、B树
    • 4.1 定义
    • 4.2 插入
  • 5、B+树

引言

二叉树的局限性:

详解多路查找树(2-3树、2-3-4树、B树、B+树)以及python实现相关操作_第1张图片
\quad \quad 二叉树需要加载到内存的,如果二叉树的节点少,没有什么问题,但是如果二叉树的节点很多,就存在一下问题:

  • 在构建二叉树时,需要多次进行i/o(存取)操作(海量数据存在数据库或文件中),节点数量,构建二叉树时,速度有影响。
  • 节点数量,也会造成二叉树的高度很大,会降低操作速度

\quad \quad 我们之前谈的树,都是一个节点可以有多个孩子,但是它自身只存储一个元素。二叉树限制更多,节点最多只有两个孩子。

\quad \quad 一个节点只能存储一个元素,在元素非常多的时候,就使得要么树的度非常大(节点拥有子树的个数的最大值),要么树的高度非常大,甚至两者都必须足够大才行。这就使得内存存取外存次数非常多,这显然成了时间效率上的瓶颈,这迫使我们要打破每一个节点只存储一个元素的限制,为此引入了多路查找树的概念。

1、概述

\quad \quad 多路查找树(multi-way search tree),其每一个节点的孩子数可以多于两个,且每一个节点处可以存储多个元素,所有元素之间存在某种特定的排序关系。主要有四种特殊形式:2-3树、2-3-4树、B树、B+树。

2、2-3树

2.1 定义

\quad \quad 2-3树是这样的一棵多路查找树:其中的每一个结点都具有两个孩子(我们称它为2结点)或三个孩子(我们称它为3结点)。

\quad \quad 一个2结点包含一个元素和两个孩子(或没有孩子),且与二叉排序树类似,左子树包含的元素小于该元素,右子树包含的元素大于该元素。不过,与二叉排序树不同的是,这个2结点要么没有孩子,要么就有两个,不能只有一个孩子。

\quad \quad 一个3结点包含一大一小两个元素和三个孩子(或没有孩子), 一个3结点要么没有孩子,要么具有3个孩子。如果某个3结点有孩子的话,左子树包含小于较小元素的元素,右子树包含大于较大元素的元素,中间子树包含介于两元素之间的元素。

\quad \quad 另外,2-3树中所有的叶子都在同一层次上。如下图,就是一棵有效的2-3树。

详解多路查找树(2-3树、2-3-4树、B树、B+树)以及python实现相关操作_第2张图片

2.2 插入操作

1)对于空树,插入一个2结点即可。

2)插入结点到一个2结点的叶子上。直接将这个结点放进2结点叶子,使得2结点叶子变成3结点叶子。

  • 如图8-8-3所示,在左图的2-3树种插入元素3,根据遍历可知,3比8小,比4小,于是就只能插入到叶子节点1的位置,因此可将此节点变成3结点,即右图完成插入过程。当然,插入元素还要与当前叶子结点的元素比较大小,小的放在左边,大的放在右边。
    详解多路查找树(2-3树、2-3-4树、B树、B+树)以及python实现相关操作_第3张图片

3)插入结点到一个3结点的叶子上。因为3结点本身已经是2-3树的结点最大容量,已经有两个元素,因此就需要将其拆分,且将树中两元素或插入元素的三者中选择其一向上移动一层。

  • 第一种情况,插入结点到3结点的叶子,其双亲结点为2结点,则将其双亲变为3结点,自己仍然保持3结点。

详解多路查找树(2-3树、2-3-4树、B树、B+树)以及python实现相关操作_第4张图片

  • 另一种情况,插入结点到3结点的叶子,其双亲结点为3结点,其祖父结点为2结点,则将其祖父结点变为3结点,拆分插入结点的3结点和双亲结点都变为2结点,同时保持所有的叶子结点都在同一层次上。
    详解多路查找树(2-3树、2-3-4树、B树、B+树)以及python实现相关操作_第5张图片

  • 最后一种情况,插入结点到3结点的叶子,其双亲结点为3结点,其祖父结点也为3结点,则拆分插入结点的3结点、双亲结点以及祖父结点都变为2结点,同时使得树的高度增加一层。

详解多路查找树(2-3树、2-3-4树、B树、B+树)以及python实现相关操作_第6张图片
详解多路查找树(2-3树、2-3-4树、B树、B+树)以及python实现相关操作_第7张图片

2.3 删除操作

\quad \quad 2-3树的删除也分为三种情况:

  1. 若所删除元素位于一个3结点的叶子结点上,则直接在该结点处删除该元素即可。
    详解多路查找树(2-3树、2-3-4树、B树、B+树)以及python实现相关操作_第8张图片
  2. 若所删除元素位于一个2结点上,即要删除的是只有一个元素的结点,分为以下四种情形进行相关处理:
  • 此节点的双亲也是2结点,且拥有一个3结点的右孩子,则删除元素并进行左旋。
    详解多路查找树(2-3树、2-3-4树、B树、B+树)以及python实现相关操作_第9张图片
  • 此节点的双亲是2结点,且右孩子也是2结点。

  • 详解多路查找树(2-3树、2-3-4树、B树、B+树)以及python实现相关操作_第10张图片

详解多路查找树(2-3树、2-3-4树、B树、B+树)以及python实现相关操作_第11张图片详解多路查找树(2-3树、2-3-4树、B树、B+树)以及python实现相关操作_第12张图片

  1. 若所删除元素位于非叶子的分支结点,则将树按中序遍历后得到此元素的前驱或后继元素进行补位。

3、2-3-4 树

\quad \quad 2-3-4 树是2-3树的扩展,包括了4结点的使用。
\quad \quad 一个4结点包含小中大3个元素和4个孩子(或没有孩子),一个4结点要么没有孩子,要么具有4个孩子。如果某个4结点有孩子的化,左子树包含小于最小元素的元素;第二字子树包含大于最小元素,小于第二元素的元素;第三子树包含大于第二元素,小于最大元素的元素;右子树包含大于最大元素的元素。

4、B树

4.1 定义

\quad \quad B树是一种平衡的多路查找树,2-3树和2-3-4树都是B树的特例。

  • 结点最大的孩子数目称为B树的阶
  • 所以2-3树就是3阶B树,二叉树就是2阶B树,2-3-4树是4阶B树。

\quad \quad 一个m阶的B树具有如下属性:

  • 如果根节点不是叶节点,则其至少有两颗子树。
  • 所有叶子节点都位于同一层次。
  • 每一个非根的分支结点都有k-1个元素和k个孩子,其中 ┌ m / 2 ┐ ≤ k ≤ m ┌m/2┐\leq k\leq m m/2km.;每一个叶子结点n都有k-1个元素,其中 ┌ m / 2 ┐ ≤ k ≤ m ┌m/2┐\leq k\leq m m/2km。其中, ┌ ┐ ┌ ┐ 是向上取整。
  • 详解多路查找树(2-3树、2-3-4树、B树、B+树)以及python实现相关操作_第13张图片

4.2 插入

\quad \quad 对于B树来说,与二叉搜索树相同,插入操作一定是发生在叶子节点上。可与二叉搜索树不同的是,B树插入一节点的过程可能会对该树的其余结构产生连锁反应。关于B树的插入操作,和2-3树一样,只不过阶数可能会大了些。

在B树上的查找过程是一个顺指针查找节点和在节点中查找关键字的交叉过程。

关于B树的插入删除,和2-3树一样,只不过阶数可能会大了些。

5、B+树

B+Tree是在B-Tree基础上的一种优化,使其更适合实现外存储索引结构,InnoDB存储引擎就是用B+Tree实现其索引结构。

从上一节中的B-Tree结构图中可以看到每个节点中不仅包含数据的key值,还有data值。而每一个页的存储空间是有限的,如果data数据较大时将会导致每个节点(即一个页)能存储的key的数量很小,当存储的数据量很大时同样会导致B-Tree的深度较大,增大查询时的磁盘I/O次数,进而影响查询效率。在B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样可以大大加大每个节点存储的key值数量,降低B+Tree的高度。

B+Tree相对于B-Tree有几点不同:

非叶子节点只存储键值信息。
所有叶子节点之间都有一个链指针。
数据记录都存放在叶子节点中。
将上一节中的B-Tree优化,由于B+Tree的非叶子节点只存储键值信息,假设每个磁盘块能存储4个键值及指针信息,则变成B+Tree后其结构如下图所示:

未完待续
参考资料:
1、《大话数据结构》
2、https://blog.csdn.net/u010707262/article/details/103546589
3、https://blog.csdn.net/qq_21993785/article/details/80576642
4、

你可能感兴趣的:(数据结构与算法,#,数据结构,多路查找树,数据结构,查找)