详细介绍了多路查找树中的2-3树、2-3-4树、B树、B+树的概念的区别,以及它们的应用场景。

文章目录

  • 1 多路查找树的概述
    • 1.1 索引概述
    • 1.2 多路查找树的引出
  • 2 2-3树
    • 2.1 2-3树查找的实现
    • 2.2 2-3树插入的实现
    • 2.3 2-3树删除的实现
  • 3 2-3-4树
    • 3.1 2-3-4树的插入操作
    • 3.2 2-3-4树的删除操作
    • 3.3 总结
  • 4 B树
    • 4.1 B树查找算法分析
    • 4.2 B树的插入和删除
  • 5 B+树
  • 5.1 总结

1 多路查找树的概述

1.1 索引概述

一般来说,我们操作的数据都是存储在内存(CPU)中的,但如若我们要操作的数据集非常大,大到内存已经没办法处理了怎么办呢?如数据库中的上千万条记录的数据表、硬盘中的上万个文件等,他们必然不能都存储在内存中,而是存储在外存中的。

对于外存中的数据,常见如数据库,我们通常通过索引表来进行数据查找和交互,一般来说,索引表本身也很大,因为数据库的数据非常多,因此索引也不可能全部存储在内存中,因此索引表往往也是以索引文件的形式存储的磁盘上。Mysql的MyISAM引擎的索引文件和数据文件是分离的,一张数据库表就有它对应的索引表,索引表中一个索引对应一条数据库记录的磁盘地址,内存中发起请求通过指定索引的查找索引表即可定位唯一的一条数据;当然Mysql的InnoDB引擎的索引表也是数据表,即索引表保存了索引和完整的数据记录。但是不管怎么说数据的查找都会依赖索引,并且建议通过索引查找,因为如果没有走索引,那就会走全表扫描,使得查找效率大大降低。

因为索引文件同样存储在磁盘上,这样的话,索引查找过程中每查找一次就要产生一次磁盘I/O消耗,相对于CPU存取,I/O存取的消耗要高几个数量级,访问磁盘的成本大概是访问内存的十万倍左右。关于cpu和磁盘速度对比:链接。

实际上,考虑到磁盘IO是非常高昂的操作,计算机操作已经系统做了一些优化,当一次IO时,不光把当前磁盘地址的数据,而是把相邻的数据也都读取到内存缓冲区内,局部预读性原理告诉我们,当计算机访问一个地址的数据的时候,与其相邻的数据也会很快被访问到。

每一次IO读取的数据我们称之为一页(page)。具体一页有多大数据跟操作系统有关,一般为4k或8k大小的连续磁盘块,也就是我们读取一页内的数据时候,实际上才发生了一次IO,这个理论对于索引的数据结构设计非常有帮助,通常,索引节点的大小被设计为一页的大小。

1.2 多路查找树的引出

对于一旦涉及到这样的外部存储设备(外存),关于时间复杂度的计算就会发生变化,访问某个表/集合元素的时间已经不仅仅是寻找该元素所需比较次数的函数,我们必须考虑对硬盘IO进行操作的时间。由于IO耗时远大于CPU耗时,所以此处评价一个数据结构作为索引的优劣最重要的指标就是要尽量减少查找过程中磁盘IO的存取次数

我们之前谈的树,都是一个节点可以有多个孩子,但是它自身只存储一个元素。二叉树限制更多,节点最多只能有两个孩子。一个节点只能存储一个元素,在元素非常多的时候,就使得要么树的度非常大(节点拥有子树的个数的最大值),要么树的高度非常大,甚至两者都必须足够大才行,这就使得IO次数非常多,这显然成了时间效率上的瓶颈,并且由于一次IO读取一个节点的数据,普通二叉树并不能容纳更多的数据,这样又造成了磁盘块空间的浪费。

以上种种限制迫使我们设计出每一个节点可以存储多个元素,并且数据结构的高度可控的数据结构,为此引入了多路查找树的概念。一颗平衡多路查找树同样可以使得数据的查找效率保证在O(logN)这样的对数级别上,此时底数为叉数或者阶。

多路查找树(muitl-way search tree),其每一个节点的孩子数可以多于两个,且每一个节点处可以存储多个元素。由于它是一颗平衡查找树,所有元素之间存在某种特定的排序关系。在这里,每一个节点可以存储多少个元素,以及它的孩子数的多少是非常关键的。为此,我们讲解它的4种特殊形式:2-3树、2-3-4树、B树和B+树。

2 2-3树

2-3树是一种比较早期的自平衡多路查找树,构建跟维系一棵2-3树,比平衡二叉树要复杂的多。因此学习2-3树以及其他多路查找树还需要平衡二叉树的知识:平衡二叉树(AVL树)的详解以及Java代码的完全实现。

2-3树中的一个节点可能具有两个孩子,我们称它为2-节点;或三个孩子,我们称它为3-节点。后面会讲道实际上它就是一颗B树。它的节点具有如下性质:

  1. 一个2节点包含一个元素和两个孩子(或没有孩子),且与二叉排序树类似,左子树包含的元素小于该元素,右子树包含的元素大于该元素。不过,与二叉排序树不同的是,这个2节点要么没有孩子,要有就有两个,不能只有一个孩子。
  2. 一个3节点包含一小一大两个元素和三个孩子(或没有孩子),一个3节点要么没有孩子,要么具有3个孩子。如果某个3节点有孩子的话,左子树包含小于较小元素的元素,右子树包含大于较大元素的元素,中间子树包含介于两元素之间的元素。
  3. 2-3树中所有的叶子都在同一层次上,因此是一颗平衡排序树。其时间复杂度和AVL树一样都是O(logN)。

如下图所示,就是一棵2-3树:

2.1 2-3树查找的实现

跟二叉排序树的查找类似:从根节点开始比较,若相等,则结束。如果小于根节点,则说明它应该在左边,选定左节点进行比较;如果大于根节点,则说明在右边,选定右节点进行比较,如不相等,则继续循环。如到最后访问到空节点,则说明没找到。

只不过对于3节点的情况,就需要判断左中右子树,原理一样,在此不再赘述。

2.2 2-3树插入的实现

对于2-3树的插入来说,与平衡二叉树相同,插入操作一定是发生在叶子节点上,并且节点的插入和删除都有可能导致不平衡的情况发生,在插入和删除节点时也是需要动态维持平衡的,但维持平衡的策略和AVL树是不一样的。

AVL树向下添加节点之后通过旋转来恢复平衡,而2-3树是通过节点向上分裂来维持平衡的,也就是说2-3树插入元素的过程中层级是向上增加的,因此不会导致叶子节点不在同一层级的现象发生,也就不需要旋转了。2-3树插入可分为三种情况:

第一种情况:对于空树,插入一个2-节点,让其成为根节点即可,这很容易理解。

第二种情况:插入节点到一个2-节点的叶子上。

由于其本身就只有一个元素,所以只需要将其升级为3-节点即可。

如下图所示。我们希望从左边的2-3树中插入元素3,根据遍历可知,3比8小、比4小,于是就只能考虑插入到叶子节点1所在的位置,因此很自然的想法就是将此节点变成一个3-节点,即右图这样完成插入操作。当然,要视插入的元素与当前叶子节点的元素比较大小后,决定谁在左谁在右。例如,若插入的是0,则此节点就是“0”在左“1”在右了。

第三种情况:要往3-节点中插入一个新元素。因为3-节点本身已经是2-3树的节点最大容量(已经有两个元素),因此就需要将其向上分裂。

向一颗只含有一个3-节点的树中插入元素:

先临时将新元素存入该节点中,使之成为一个4节点。然后再进行向上分裂,节点的三个元素中,位于中间的元素成为根节点,左右两个元素分别成为一个2节点作为左右子树。

向一个父节点为2-节点的3-节点中插入元素:
构造一个临时的4-节点并将其向上分裂,但此时我们不会为中键创建一个新节点,而是将其移动至原来的父节点中。

如下图,需要向左图中插入元素5。经过遍历可得到元素5比8小比4大,因此它应该是需要插入在拥有6、7元素的3节点位置。问题就在于,6和7节点已经是3节点,不能再加。此时发现它的双亲节点4是个2节点,因此考虑让它升级为3节点,这样它就得有三个孩子,于是就想到,将6、7节点拆分,让6与4结成3节点,将5成为它的中间孩子,将7成为它的右孩子,如下图的右图所示。

向一个父节点为3-节点的3-节点中插入元素。

同样先构造一个临时的4-节点并将其向上分裂,由于此时父节点已经是3-节点,因此父节点也变成了4-节点,需要继续向上分裂,直到某个父节点不是4-节点为止,如果到了根节点还是4-节点,那么根节点继续向上分裂,此时树的层级会增加一层,当然不利于查找。

如上图所示,需要向图中插入元素7。经过遍历可得到元素7应该被插入在拥有5、6元素的3-节点位置,此时先临时插入7,使其成为4-节点。

然后向上分裂,此时父节点也成为4-节点:

此时父节点只能继续向上分裂,直到根节点——因为它是2-节点,因此会变成3-节点,并没有超出2-3树的定义,分裂结束。

如果此时再插入18,那么会如上面一样就行向上分裂,但此时根节点已经是3-节点了,在合并一个节点会成为4-节点,此时根节点会向上分裂,增加一层,形成下图4的结构:

以上就是2-3树插入节点同时动态维持平衡的方法,自始至终叶子节点均在同一层级上。只有当根节点是4-节点时,拆分后树的高度才加一!

2.3 2-3树删除的实现

2-3树的删除也分为三种情况,与插入相反。以下图的2-3树为例:

当删除元素位于3-节点的叶子节点上:

只需要在该节点处删除该元素即可,不会影响到整棵树的其他节点结构。

例如,想要删除5,那么直接删除即可:

当删除元素位于非叶子节点:

使用中序遍历找到待删除节点的后继节点,然后将后继节点与待删除节点位置互换,此时就将问题转化为删除节点为叶子节点(平衡树的非叶子节点中序遍历后继节点肯定是叶子节点),如果该叶子是3-节点,则跟情况(1)一样,如果该节点是2-节点,则跟后面的情况(3)一样;

当删除元素位于2-节点的叶子节点上:

如果按照以前树的理解,删除即可,可现在的2-3树的定义告诉我们这样做是不可以的。可能会导致不平衡的情况发生。比如下图所示,如果我们删除了节点0,那么父节点本来是一个3-节点(它必须拥有3个孩子),此时它就不满足定义了。

因此,对于删除叶子节点是2节点的情况,我们需要分多种情形来处理。总结起来就是当前待删除2-叶子节点,兄弟节点与父节点,分别是2-节点还是3-节点的情况,即:

父节点为2-节点,且拥有一个3-节点的兄弟节点。

将父节点移动到当前位置,再将兄弟节点中最接近当前位置的key移动到双亲节点中

父节点为3-节点。 即此时有两个兄弟节点,而兄弟节点又可能有多种情况,穷举起来有:删除节点的位置左中右3个,以及另外两个兄弟节点是否为2-节点或3-节点的4种情况,总共3*4=12种。即:

  1. 若删除的是左或右节点,且中间节点为2-节点,则此时父节点的左或右key下移,与中间节点合并,此时父节点为2-节点,两个子节点,树满足2-3树,完成调整;
  2. 若删除的是左或右节点,且中间节点为3-节点,则此时父节点的一个key下移,中间节点的一个key上移与父节点合并,此时父节点为3-节点,3个子节点,树满足2-3树,完成调整;
  3. 若删除的是中间节点,且右节点为2-节点,则此时父节点的一个key下移,与右节点合并,此时父节点为为2-节点,两个子节点,树满足2-3树,完成调整;
  4. 若删除的是中间节点,且右节点为3-节点,则此时父节点的一个key下移,右节点的一个key上移与父节点合并,此时父节点为3-节点,3个子节点,树满足2-3树,完成调整。

1与2删除左或右节点两种情况,中间节点2-节点或3-节点两种情况,兄弟节点2-节点或3-节点两种情况,总共 2x2x2=8 种;删除中间节点一种情况,iii与iv右节点2-节点或3-节点两种情况,左节点2-节点或3-节点两种情况,总共 1x2x2=4 种; 4+8=12 种全齐,虽然场景有12种,但是处理的方式只有2种,一种是父节点下移与子节点合并,另一种是父节点下移成单独一个子节点,然后3-节点的子节点上移一个key与父节点合并。

父节点为2-节点,且拥有一个2-节点的兄弟节点。

先通过移动兄弟节点的中序遍历直接后继到兄弟节点,以使兄弟节点变为3节点;再对该节点进行删除操作。

如下案例,需要删除5进行的一系列操作。



在移动节点11到10的位置上时,实际上就是发生了2-3树节点删除的情况2。上图是调整后的结构。

3 2-3-4树

2-3-4树只是在2-3树的基础上进行了扩展。2-3-4树也是一棵自平衡的多路查找树,具有如下性质:

  1. 任一节点只能是1个或2个或3个key,对应的子节点为2个子节点或3个子节点或4个子节点;
  2. 所有叶子节点到根节点的长度一致;
  3. 每个节点的key从左到右保持了从小到大的顺序,两个key之间的子树中所有的key一定大于它的父节点的左key,小于父节点的右key,对于3个key的节点,两两key之间也是如此。

下图就是一颗典型的2-3-4树:

3.1 2-3-4树的插入操作

2-3-4树插入节点跟删除节点的处理,实际上跟2-3树很像,特别是插入节点,基本上跟2-3树是一模一样,只是分裂的条件由3-节点变成了4-节点而已,即,

  1. 如果待插入的节点不是4-节点,则直接插入即可;
  2. 如果待插入的节点是4-节点,则先把新节点临时插入进去变成5-节点,然后对5节点进行向上分裂、合并,5-节点分裂成两个2-节点(5-节点最小的元素、5-节点第二个元素)、1个3-节点(5-节点后两个元素),然后将分裂之后的第2个2-节点向上合并到父节点中,然后把父节点作为插入元素之后的当前节点,重复(1)、(2)步骤,直到满足2-3-4树的定义性质。

例如,需要对上图的2-3-4树插入23:


2-3-4树节点的插入也比较简单的,其实从前面到这里可以看出一些规律,就是不管是二叉排序树也好,还是平衡二叉树,以及2-3树的节点插入,相对来说都算简单,但是对于一棵树节点的删除却比较复杂,有的甚至需要不断的回溯到根节点才能把树调整平衡。

所以,关于2-3-4树节点的删除也不简单,至少比节点的插入要复杂麻烦的多。

3.2 2-3-4树的删除操作

  1. 当删除的节点是非2-节点的叶子节点,则将要删除的目标key删除即可;
  2. 当删除的节点是非叶子节点,先使用中序遍历找到待删除节点的后继节点,然后将后继节点与待删除节点位置互换,此时就将问题转化为删除节点为叶子节点(平衡树的非叶子节点中序遍历后继节点肯定叶子节点),如果该叶子是非2-节点,则跟情况(1)一样,如果该节点是2-节点,则跟后面的情况(3)一样;
  3. 当删除的节点是2-节点的叶子节点,则将节点删除,此时树肯定需要调整,即:
    1. 当父节点是2-节点,兄弟节点是非2-节点: 将兄弟节点的一个key上移成父节点,而父节点下移成子节点,此时树满足2-3-4树,完成调整。
    2. 当父节点是2-节点,兄弟节点也是2-节点: 先通过移动兄弟节点的中序遍历直接后继到兄弟节点,以使兄弟节点变为3-节点;再对该节点进行删除操作。
    3. 当父节点是非2-节点,即此时有两个或三个兄弟节点,此时看相邻兄弟节点是否“丰满”,也即是否为4-节点,如下:
      1. 若删除节点的相邻兄弟节点为非4-节点,则父节点的一个key下移,与相邻兄弟节点合并,此时树满足2-3树,完成调整;
      2. 若删除节点的相邻兄弟节点为4-节点,则父节点的一个key下移成1个key的节点,相邻兄弟节点的一个key上移与父节点合并,此时树满足2-3树,完成调整;

可以看出来,2-3-4树的删除操作虽然比较复杂,但是和2-3树的删除操作非常相似,我们理解其中一种树的操作,那么理解另外一种树的删除操作就是非常简单的一件事了。

3.3 总结

对于2-3树和2-3-4树的删除与插入,都是以保持叶子节点的深度相同为基础的。自始至终叶子节点均在同一层级上。

插入的时候,即标准的二叉树的的高度是由上到下的增加的,而2-3树和2-3-4树的高度生长是由下至上的。删除的时候不断的用上边的节点来弥补下边的节点,保持地基的稳定,再缩减高度。

2-3树、2-3-4树和平衡二叉树的查找时间复杂度都是O(logN),但是2-3树和2-3-4树的节点能够保存更多的数据,并且拥有更低的深度,在常被用来构建需要内、外存交互的数据结构,能够有效的降低IO次数,提升查找效率。但是最常见的数据库索引表却不是基于2-3树或者2-3-4树来实现的,因为后来又有了更加高效的平衡多路查找树结构。

理解2-3-4树还是理解红黑树的基础,通过简单的规则它们可以互相转换!

4 B树

B树(Balance Tree)由Rudolf Bayer, Edward M. McCreight于1970发表的一篇论文《Organization and Maintenance of Large Ordered Indices》中首次提出。

B树(B-tree)是一种自平衡的多路查找树,也称B-树,节点最大的孩子数目称为B树的阶(order)。2-3树和2-3-4树都是B树的特例,因此,2-3树是3阶B树,2-3-4树是4阶B树。

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

  1. 它是一颗平衡查找树,所有节点关键字是按递增次序排列,并遵循左小右大原则;
  2. 根节点或者是叶节点,或者最少有2个子节点,最多有m个子节点;
  3. 非根节点或者是叶节点,或者最少有ceil(m/2)个子节点,最多有m个子节点;
  4. 根节点的关键字数量大于等于1,小于等于m-1;(注:ceil()是个朝正无穷方向取整的函数 如ceil(1.1)结果为2);
  5. 非根节点的关键字数量大于等于ceil(m/2)-1个且小于等于m-1个
  6. 一个k-节点(2<=k<=m),要么有k个子节点,要么没有子节点;
  7. 所有叶子节点都位于同一层,或者说根节点到每个叶子节点的长度都相同。

和平衡二叉树一样,B树也能以O(logn)的时间复杂度运行进行查找、顺序读取、插入和删除的数据结构。

不同的是,平衡二叉树是一般是用于优化内存中的数据的查找速度的数据结构,B树一般用于优化外存中数据的查找数据的数据结构,普遍运用在数据库索引结构和文件系统。

对某个节点的访问就会发起一次磁盘IO请求,IO操作耗时远大于内存中操作的耗时。如果一棵B树的阶为1001(即1个节点包含1000个关键字),高度为2,它可以储存超过10亿个关键字。那么在这棵树上,寻找某一个关键字至多需要两次硬盘的读取即可。如果采用二叉树来存储这10亿个关键字,那么会需要非常多次数的IO请求。

由于B-tree每个节点能包含比二叉树更多的数据,同时树的层级比原来的二叉树更少的特性,加上数据库充分利用了磁盘块的原理(磁盘数据存储是采用块的形式存储的,每个块的大小为4k或8k,每次IO进行数据读取时,同一个磁盘块的数据可以一次性读取出来),因此采用B树作为索引结构,能够减少定位记录时所经历IO次数,从而加快存取速度。可以说,B树的数据结构就是为内外存的数据交互准备的。

4.1 B树查找算法分析

在B-树中进行查找包含两种基本操作:

  1. 在B树中查找节点;
  2. 在节点中查找关键字。

由于B树通常存储在磁盘上, 则前一查找操作是在磁盘上进行的, 而后一查找操作是在内存中进行的, 即在磁盘上找到指针p 所指节点后,先将节点中的信息读入内存, 然后再利用顺序查找或折半查找查询等于K 的关键字。显然,在磁盘上进行一次查找比在内存中进行一次查找的时间消耗多得多。

因此,在磁盘上进行查找的次数、即待查找关键字所在节点在B树上的层次树,是决定B树查找效率的首要因素。

对于n个关键字的m阶B树,最坏情况的查找次数如下:

  1. 第一层为根,至少一个节点,根至少有两个孩子,因此在第二层至少有两个节点。
  2. 除根和树叶外,其它节点至少有ceil(m/2)个孩子,因此第三层至少有2* ceil(m/2)个节点,在第四层至少有2* ceil(m/2)^2个节点……
  3. 那么在第k+1层至少有2* ceil(m/2)^(k-1)个节点,而J+1层的节点为叶子节点,于是叶子节点的个数n+1。
  4. 若m阶B树有n个关键字,那么当你找到了叶子节点,其实也就等于查找不成功的节点为n+1,因此n+1≥2* ceil(m/2)^(k-1),即:

也就是说,在含有n个关键字的m阶B树上查找时,从根节点到关键字节点的路径上涉及的节点数不超过log((n+1)/2)+1,底数为ceil(m/2)。

4.2 B树的插入和删除

B树的插入和删除和2-3树和2-3-4树基本一致。只不过把具体的阶数采用字母代替。

插入:

对高度为h的m阶B树,新节点一般插第h层。通过检索可以确定关键码应插入的位置:

  1. 若该节点中关键码个数小于等于m-1,则直接插入就可
  2. 若该节点中关键码个数等于m-1,则将引起节点的分裂,以中间的关键码为界将节点一分为二(如果是偶数则取中偏小的关键码),产生了一个新的节点,并将中间关键码插入到父节点中;然后将父节点看作当前插入元素之后的节点,循环判断(1),(2)即可。

删除:

B树删除:首先要查找该值是否在B树中存在,如果存在,判断该元素是否存在左右孩子节点,如果有,则上移孩子节点中的相近节点(左孩子最右边的节点或者右孩子最左边的节点)到父节点中,然后根据移动之后的情况;如果没有,进行直接删除;如果不存在对应的值,则删除失败。

  1. 如果当前要删除的值位于非叶子节点,则用后继值覆盖要删除的值,再用后继值所在的分支删除该后继值。(该后继值必须位于叶子节点上)
  2. 该节点值个数不小于Math.ceil(m/2)-1(取上限函数),结束删除操作,否则下一步
  3. 如果兄弟节点值个数大于Math.ceil(m/2)-1,则父节点中下移到该节点,兄弟的一个值上移,删除操作结束。

将父节点的key下移与当前的节点和他的兄弟姐妹节点key合并,形成一个新的节点,有些节点可能有左兄弟,也有右兄弟,我们可以任意选择一个兄弟节点即可。

5 B+树

B+树可以说是B树的升级版,相对于B树来说B+树更充分的利用了节点的空间,让查询速度更加稳定,其速度完全接近于二分法查找。大部分文件系统和数据均采用B+树来实现索引结构。

一棵m阶的B+树和m阶的B树的差异在于:

  1. 有n棵子树的非叶节点中包含有n个关键字(B树中是n-1个关键字),但是每个关键字不保存数据,只用来保存叶子节点相同关键字的索引,所有数据都保存在叶子节点。(此处,对于非叶节点的m颗子树和n个关键字的关系,mysql的索引结构似乎是m=n+1,而不是上面的m=n)
  2. 所有的非叶节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。
  3. 所有的叶子节点包含全部关键字的信息,及指向含这些关键字所指向的具体磁盘记录的指针data,并且每一个叶子节点带有指向下一个相邻的叶节点指针,形成链表;

如下,是一颗典型的B树:

如下,是一颗普通定义的典型的B+树:

如下,是一颗mysql索引表中实现的一种B+树:

由上可知,B+树的具体实现是多种多样的的,我们应该记住B树和B+树的主要区别是:B+树的非叶子节点不存储数据,并且叶子节点会形成链表。链表也可以自己选择具体的实现,甚至可以是双向链表或者环形链表。

B+树的插入、删除过程也都与B树类似,只不过插入和删除的元素都是在叶子节点上进行而已,因此可能需要调整非叶节点的索引key。

5.1 总结

  1. B树的非叶节点会存储关键字及其对应的数据地址,B+树的非叶节点只存关键字索引,不会存具体的数据地址,因此B+树的一个节点相比B树能存储更多的索引元素,一次性读入内存的需要查找的关键字也就越多,B+树的高度更小,相对IO读写次数就降低了。
  2. B树的查询效率并不稳定,最好的情况只查询一次(根节点),最坏情况是查找到叶子节点,而B+树由于非叶节点不存数据地址,而只是叶子节点中关键字的索引。所有查询都要查找到叶子节点才算命中,查询效率比较稳定。这对于sql语句的优化是非常有帮助的。
  3. B+树所有叶子节点形成有序链表,只需要去遍历叶子节点就可以实现整棵树的遍历。方便数据的范围查询,而B树不支持这样的操作或者说效率太低。
  4. 现代数据库和文件系统的索引表大部分是使用B+树来实现的,但并不是全部。

相关参考:

  1. 《算法》
  2. 《算法图解》
  3. 《大话数据结构》

如果有什么不懂或者需要交流,可以留言。另外希望点赞、收藏、关注,我将不间断更新各种Java学习博客!

数据结构—2-3树、2-3-4树、B树、B+树等多路查找树的原理详解相关推荐

  1. 《数据结构与算法》(十九)- 多路查找树

    目录 前言 1. 多路查找树(B树) 1) 2-3树 1.1) 2-3树的插入实现 1.2) 2-3树的删除实现 2) 2-3-4树 3) B树 4) B+树 2. 总结 原文地址:https://p ...

  2. 数据结构与算法之多路查找树(2-3树、2-3-4树、B树、B+树)

    目录 为什么使用多路查找树 二叉树存在的问题 多路查找树 2-3树 2-3树插入的操作 2-3树删除的操作 2-3-4树 2-3-4树的插入操作 2-3-4树的删除操作 B树 B+树 总结 为什么使用 ...

  3. 数据结构 多路查找树 ---------B树和B+树的简单介绍

    参考链接:微信公众号 程序员小灰 https://mp.weixin.qq.com/s/rDCEFzoKHIjyHfI_bsz5Rw https://mp.weixin.qq.com/s/jRZMMO ...

  4. 多路查找树之2-3树的删除原理 - 数据结构和算法81

    多路查找树之2-3树的删除原理 让编程改变世界 Change the world by program 本节视频具体讲解2-3树的删除原理 ...... 省略,具体请看视频讲解 ...... [buy ...

  5. 字典树原理详解及其Python实现

    一.原理详解 1.初步介绍: 字典树又名前缀树,Trie树,是一种存储大量字符串的树形数据结构,经常被搜索引擎系统用于文本词频统计. 除此之外也常用于计算左右信息熵.计算点互信息. 下图演示了一个保存 ...

  6. 二叉排序树,AVL树,B树(多路查找树),B+树

    一.二叉排序树 1.定义: 对于一颗二叉树,它的左子树若不为空,则左子树上所有结点的值小于它的根结点的值,若右子树不为空,则右子树上的所有结点的值大于它的根结点的值.且它的左右子树也分别为二叉排序树. ...

  7. HTTP协议漫谈 C#实现图(Graph) C#实现二叉查找树 浅谈进程同步和互斥的概念 C#实现平衡多路查找树(B树)...

    HTTP协议漫谈 简介 园子里已经有不少介绍HTTP的的好文章.对HTTP的一些细节介绍的比较好,所以本篇文章不会对HTTP的细节进行深究,而是从够高和更结构化的角度将HTTP协议的元素进行分类讲解. ...

  8. 查找、检索 算法-总结5 多路查找树/B~树/B+树

    源地址:http://hxraid.javaeye.com/blog/611105 在前面专题中讲的BST.AVL.RBT都是典型的二叉查找树结构,其查找的时间复杂度与树高相关.那么降低树高自然对查找 ...

  9. 第 12 章 多路查找树

    第 12 章 多路查找树 1.二叉树与 B 树 1.1.二叉树存在的问题 二叉树的操作效率较高,但是也存在问题, 请看下面的二叉树 二叉树需要加载到内存的,如果二叉树的节点少,没有什么问题,但是如果二 ...

最新文章

  1. 洛谷-P3203 弹飞绵羊 分块
  2. gan怎么输入一维数据_时空序列预测模型GAN+LSTM
  3. Linux下启动启动tomcat 服务器报错 The file is absent or does not have execute permission
  4. python conf配置文件
  5. Windows Redis3 安装
  6. C#生成CHM文件(入门篇)
  7. 三星s9Android9内测申请链接,Galaxy S9/S9+国行版进行安卓9.0内测
  8. jquery实现多选框
  9. 前端框架中的大熊猫Ember
  10. java visual foxpro_从Java访问Visual FoxPro数据库
  11. 软件工程保研成功率_软件工程专业保研还是工作?
  12. 内定抽奖小程序_微信抽奖助手怎么中奖 无需作弊照样中奖
  13. 扫码点餐小程序项目后端开发之“01.搭建服务器基础设施”
  14. android 接口回调全面,Android 回调机制--接口回调
  15. 智慧城市智能化建设发展现状及展望
  16. Linux命令:ln -s
  17. html svg波浪,CSS实现svg图片水纹波浪流动效果
  18. win10 增加右键在此处打开命令行菜单
  19. 计算机毕业设计Java网上租房管理(源码+系统+mysql数据库+Lw文档)
  20. Idea主菜单不见了(File,View等工具栏隐藏了)

热门文章

  1. Struts2漏洞修复方案
  2. 如何发一条空白的朋友圈或者app昵称名
  3. 用Label mx条码打印软件制作吊牌标签
  4. Ubuntu 16.04-18.04中安装 WPS Office 2016 for Linux(集合篇含字体解决方法)简单好用
  5. @GenericValue和@GenericGenerator详解
  6. linux daemon安装教程,daemontools安装和使用
  7. 电脑wifi通过中继器上网频繁掉线问题分析及问题解决方案(DHCP NAK)
  8. TOSHIBA,TC358775XBG,MIPI DSI转LVDS,视频解码器,RK3399点LVDS屏必备
  9. 文件改日期 电梯卡dump_小区的电梯卡,PM3把卡信息读取出来了,看了下。不知道怎么修改。请教大神。如何修改时间。谢谢...
  10. 侯捷C++->三大函数:拷贝构造、拷贝赋值、析构