目录

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

为什么使用多路查找树

二叉树存在的问题

二叉树需要加载到内存的,如果二叉树的节点少,没有什么问题,但是如果二叉树的节点很多(比如1亿), 就存在如下问题:

  • 问题1:在构建二叉树时,需要多次进行I/O操作(海量数据存在数据库或文件中),节点海量,构建二叉树时,速度有影响.

  • 问题2:节点海量,也会造成二叉树的高度很大,会降低操作速度.

解决上述问题 —> 多叉树

多路查找树

  • 1、在二叉树中,每个节点有数据项,最多有两个子节点。如果允许每个节点可以有更多的数据项和更多的子节点,就是多叉树(multiway tree)
  • 2、后面我们讲解的"2-3树","2-3-4树"就是多叉树,多叉树通过重新组织节点,减少树的高度,能对二叉树进行优化。
  • 3、举例说明(下面2-3树就是一颗多叉树)

2-3树

2-3树定义

  • 所有叶子节点都要在同一层
  • 二节点要么有两个子节点,要么没有节点
  • 三节点要么没有节点,要么有三个子节点
  • 不能出现节点不满的情况

2-3树插入的操作

插入原理

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

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

三种插入情况

1)对于空树,插入一个2节点即可;

2)插入节点到一个2节点的叶子上。由于本身就只有一个元素,所以只需要将其升级为3节点即可(如:插入3)。


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

分为三种情况:

  • 升级父节点(插入5)
  • 升级根节点(插入11)
  • 增加树高度(插入2,从下往上拆)

2-3树删除的操作

删除原理:2-3树的删除也分为三种情况,与插入相反。

三种删除情况

1)所删元素位于一个3节点的叶子节点上,直接删除,不会影响树结构(如:删除9)

2)所删元素位于一个2节点上,直接删除,破坏树结构

分为四种情况:

  • 此节点双亲也是2节点,且拥有一个3节点的右孩子(如:删除1)

  • 此节点的双亲是2节点,它右孩子也是2节点(如:删除4)

  • 此节点的双亲是3节点(如:删除10)

  • 当前树是一个满二叉树,降低树高(如:删除8)

3)所删元素位于非叶子的分支节点。此时按树中序遍历得到此元素的前驱或后续元素,补位

两种情况:

  • 分支节点是2节点(如:删除4)
  • 分支节点是3节点(如:删除12)

2-3-4树

2-3-4树是2-3树的扩展,包括了 4 节点的使用,一个 4 节点包含小中大三个元素和四个孩子(或没有孩子)

2-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树的删除操作

删除顺序使1,6,3,4,5,2,9

B树

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

我们把结点最大的孩子树目称为B树的阶,因此,2-3树是3阶B树,2-3-4树是4阶B树

如下图,比如说要查找7,首先从外存读取得到根节点3,5,8三个元素,发现7不在,但是5、8之间,因此就通过A2再读取外存的2,6,7节点找到结束。

B树的数据结构为内外存的数据交互准备的。当要处理的数据很大时,无法一次全部装入内存。这时对B树调整,使得B树的阶数与硬盘存储的页面大小相匹配。比如说一棵B树的阶为1001(即1个节点包含1000个关键字),高度为2(从0开始),它可以存储超过10亿个关键字(1001x1001x1000+1001x1000+1000),只要让根节点持久的保留在内存中,那么在这颗树上,寻找某一个关键字至多需要两次硬盘的读取即可。

对于n个关键字的m阶B树,最坏情况查找次数计算
第一层至少1个节点,第二层至少2个节点,由于除根节点外每个分支节点至少有⌈m/2⌉棵子树,则第三层至少有2x⌈m/2⌉个节点。。。这样第k+1层至少有2x(⌈m/2⌉)^(k-1),实际上,k+1层的节点就是叶子节点。若m阶B树有n个关键字,那么当你找到叶子节点,其实也就等于查找不成功的节点为n+1,因此
n+1>=2x(⌈m/2⌉)^(k-1),即

在含有n个关键字的B树上查找时,从根节点到关键字节点的路径上涉及的节点数不超多

B+树

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

下图B树,我们要遍历它,假设每个节点都属于硬盘的不同页面,我们为了中序遍历所有的元素,页面2-页面1-页面3-页面1-页面4-页面1-页面5,页面1遍历了3次,而且我们每经过节点遍历时,都会对节点中的元素进行一次遍历

B+树是应文件系统所需而出的一种B树的变形树,在B树中,每一个元素树中只出现一次,而B+树中,出现在分支节点中的元素会被当做他们在该分支节点位置的中序后继者(叶子节点)中再次列出。另外,每一个叶子节点都会保存一个指向后一叶子节点的指针。
下图就是B+树,灰色关键字,在根节点出现,在叶子节点中再次列出

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

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

总结

  • B树的非叶节点会存储关键字及其对应的数据地址,B+树的非叶节点只存关键字索引,不会存具体的数据地址,因此B+树的一个节点相比B树能存储更多的索引元素,一次性读入内存的需要查找的关键字也就越多,B+树的高度更小,相对IO读写次数就降低了。

  • B树的查询效率并不稳定,最好的情况只查询一次(根节点),最坏情况是查找到叶子节点,而B+树由于非叶节点不存数据地址,而只是叶子节点中关键字的索引。所有查询都要查找到叶子节点才算命中,查询效率比较稳定。这对于sql语句的优化是非常有帮助的。

  • B+树所有叶子节点形成有序链表,只需要去遍历叶子节点就可以实现整棵树的遍历。方便数据的范围查询,而B树不支持这样的操作或者说效率太低。

  • 现代数据库和文件系统的索引表大部分是使用B+树来实现的,但并不是全部

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

  1. 对分查找的最多次数_Java数据结构与算法:多路查找树

    作者:subeiLYhttps://blog.csdn.net/m0_46153949/article/details/106742330 本章思维导图 二叉树与B树 二叉树的问题分析二叉树的操作效率 ...

  2. 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)

    常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...

  3. 数据结构与算法:二分查找

    二分查找是搜索算法中的一种,用来搜索有序数组 二分查找: 是一种简单算法,其输入是一个有序的元素列表(必须有序的原因稍后解释).如果要 查找的元素包含在列表中,二分查找返回其位置:否则返回null. ...

  4. 【python】数据结构与算法之二分查找

    一.查找 在一组数据中找某一个特定项的算法过程 通常用来判断某个特定项是否在一组数据中,最终返回True或False 常用的查找算法:顺序查找.二分查找.树表查找.哈希查找等 二.二分查找 二分查找又 ...

  5. 【数据结构与算法】二分查找

    一.什么是二分查找? 二分查找针对的是一个有序的数据集合,每次通过跟区间中间的元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间缩小为0. 二.时间复杂度分析? 1.时间复杂度 ...

  6. 数据结构与算法《二分查找》

    数据结构与算法(java)<二分查找> 基本二分查找public class BinarySearch {/*** 1.定义一个有序数组,* 2.定义两个变量i,j* 3.定义一个待查找的 ...

  7. 【数据结构与算法】插值查找算法、斐波那契查找算法(黄金分割法)的介绍和程序实现

    目录 1. 插值查找算法 1.1 插值查找算法的介绍 1.2 插值查找算法的程序实现 2. 斐波那契查找算法 2.1 斐波那契查找算法的介绍 2.2 斐波那契查找算法的程序实现 1. 插值查找算法 1 ...

  8. 【算法】多路查找树 B树 B+树

    文章目录 1.概述 1.1 多叉树 1.2 B树的基本介绍 1.3 2-3树基本介绍 1.3.1 2-3树应用案例 2 B树 B+树 B*树 2.1 B树 2.2 B+树 2.3 B*树 本文为博主九 ...

  9. vue 怎么样不重复往数组里插入数据_前端数据结构与算法(1) -二分查找vs二叉树...

    今天给大家开始介绍前端方面的数据结构,刚把vue源码过完就开始数据结构,可见它的地位有多重要.有人说我一前端又不是后端学这个数据结构干嘛,好吧,只能说你还没有这个意识,一是面试很多大厂就会考察,我面试 ...

最新文章

  1. python就业方向选择-学完Python,你有哪些就业方向可以选?
  2. Struts2---入门
  3. 计算机系统和中断的概念
  4. jQuery中map方法
  5. java yeild_Java 中 Thread.yield() 方法详解
  6. javascript-分支与循环
  7. Python常用小技巧(二)——打开图片
  8. cron linux_如何在Linux中使用cron
  9. 中华人民共和国公安部令 第 82 号- 互联网安全保护技术措施规定
  10. webpack遇见的坑:Please install 'webpack-cli' in addition to webpack itself to use the CLI.
  11. mybatis注解开发-动态SQL
  12. 九九乘法表新打表(倒三角式)
  13. 数据库与excel数据对比
  14. FPAG—UART串口实现与解析-黑金fpga资料解析
  15. [《不敢说爱的年纪》小个子的小说集]2012年8月28日
  16. 怎样找回win7密钥
  17. Qt文档阅读笔记-Ping Pong States Example解析
  18. 日语动词活用和变化规则及用法
  19. 每天15分钟,就能轻松告别拖延症
  20. Ubuntu上安装QQ2015

热门文章

  1. 1.1 java基础
  2. 2018华为云区块链全球开发者大赛——小链接 大未来
  3. 如何在 Ubuntu 18.04 LTS 中配置 IP 地址?
  4. opencv+对图片实现聚光灯效果
  5. Bugku Misc 清凉一夏 wp
  6. 【线段树套KD树】[BZOJ4605]崂山白花蛇草水
  7. 理解微分方程和线性代数的联系
  8. [除錯]引動過程的目標傳回例外狀況
  9. 锤子android 7,锤子正式加入安卓7.1.1阵容 一加3/3T尝鲜氢OS公测版
  10. 区块链技术的应用可能会带来哪些风险?