java数据结构——平衡二叉树、B树、B+树

一、平衡二叉树

1、有序二叉树可能存在的问题

给一个数列{1,2,3,4,5,6},要求创建一颗二叉排序树(BST)并分析问题所在
在这里插入图片描述

  1. 左边子树全为空,更像是一个链表
  2. 插入速度没有影响
  3. 查询速度明显降低,不能发挥二叉树的优势,同时需要每次访问左子树,导致查询速度甚至小于单链表

解决方法:平衡二叉树

2、平衡二叉树的介绍

平衡二叉树具有以下特点:
1)它是一颗空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两颗子树都是一颗平衡二叉树。
2)平衡因子: 左子树的高度 - 右子树的高度
我们将平衡因子的绝对值小于1的的有序二叉树称为平衡二叉树

3、构建平衡二叉树的思路

四种旋转类型的旋转
①:LL型旋转-----(中为支,高右转)

1.将A的左孩子B提升为新的根节点
2.将原来的根节点A降为B的右孩子
3.将各子树按大小关系连接

在这里插入图片描述

②:RR型旋转-----(中为支,高左旋)

1.将A的右孩子B升为新的根节点
2.将原来的根节点降为左孩子
3.将各子树按大小关系连接

在这里插入图片描述

③:LR型旋转-----(下二整体先旋转,后与LL同)

1.将B的左孩子C提升为新的根节点
2.将原来的跟节点A降为C的右孩子
3.将各子树按大小关系连接

在这里插入图片描述

④:RL型旋转-----(下二整体先右转,后与RR同)

1.将B的左子树C提升为新的根节点
2.将原来的根节点A降为C的左孩子
3.将各子树按大小关系连接

在这里插入图片描述

平衡的调整步骤

  1. 如果插入一个新节点,造成了不平衡,则需要调整
  2. 判断旋转类型
  3. 调整

二、B树

1、认识2-3查找树

二叉排序树简单的实现在多数情况能够达到预期的查找效率,但是每个节点只能存储一个元素和只能有两个孩子,使得在大量数据下会造成二叉排序树的深度特别大,那么在进行查找时多次的访问会造成查找效率的下降,同时,在对二叉查找树进行插入时,可能会破坏二叉查找树的平衡。为了降低对于树的访问次数,实现树的平衡,我们需要新的数据结构来处理这样的问题。
2-3查找树的定义
2-节点
包含一个键(及其对应的值)和两条链,左连接指向2-3树中都小于该节点,右链接所指向的值都大于该节点。
3-节点
包含两个键(及其对应的值)和三条链,左链接指向2-3树中的键都小于该节点,中链接指向的2-3树中的键都位于该节点的两个键之间,右连接指向的2-3树中的键都大于该节点。
在这里插入图片描述

2、B树的特点

B树中允许一个节点包含多个Key,可以是3个、4个、5个甚至是更多,并不确定,需要看具体实现。现在我们选择一个参数M来构建一个B树,我们可以将其称为M阶的B树。那么这棵树会有以下特点:

  1. 每个节点最多有M-1个Key,并且以升序排列
  2. 每个节点最多能有M个子节点
  3. 根节点至少有两个子节点

在这里插入图片描述
在实际应用中B树的阶数一般比较大(通常大于100),所以,即使存储大量的数据,B树的高度仍然比较小,这样在某些引用场景下,就能体现出他的优势

3、B树在磁盘当中的应用

磁盘能够保存大量的数据,从GB一直到TB级,但是 他的读取速度比较慢,因为涉及到机器操作,读取速度为毫秒级 。

在这里插入图片描述
磁盘由盘片构成,每个盘片有两面,又称为盘面 。盘片中央有一个可以旋转的主轴,他使得盘片以固定的旋转速率旋转,通常是5400rpm或者是7200rpm,一个磁盘中包含了多个这样的盘片并封装在一个密封的容器内 。盘片的每个表面是由一组称为磁道同心圆组成的 ,每个磁道被划分为了一组扇区 ,每个扇区包含相等数量的数据位,通常是512个子节,扇区之间由一些间隙隔开,这些间隙中不存储数据 。
在这里插入图片描述
磁盘用磁头来读写存储在盘片表面的位,而磁头连接到一个移动臂上,移动臂沿着盘片半径前后移动,可以将磁头定位到任何磁道上,这称之为寻道操作。一旦定位到磁道后,盘片转动,磁道上的每个位经过磁头时,读写磁头就可以感知到该位的值,也可以修改值。对磁盘的访问时间分为 寻道时间旋转时间,以及传送时间

由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费,因此为了提高效率,要尽量减少磁盘I/O,减少读写操作。 为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。这样做的理论依据是计算机科学中著名的局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用。由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此预读可以提高I/O效率。

页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割为连续的大小相等的块,每个存储块称为一页(1024个字节或其整数倍),预读的长度一般为页的整倍数。主存和磁盘以页为单位交换数据。当程序要读取的数据不在主存中时,会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页载入内存中,然后异常返回,程序继续运行。

文件系统的设计者利用了磁盘预读原理,将一个结点的大小设为等于一个页(1024个字节或其整数倍),这样每个结点只需要一次I/O就可以完全载入。那么3层的B树可以容纳102410241024差不多10亿个数据,如果换成二叉查找树,则需要30层!假定操作系统一次读取一个节点,并且根节点保留在内存中,那么B树在10亿个数据中查找目标值,只需要小于3次硬盘读取就可以找到目标值,但红黑树需要小于30次,因此B树大大提高了IO的操作效率。

三、B+树

1、B+树的结构特点
  1. 非叶子节点仅具有索引作用,也就是说,非叶子节点只能存储Key,不能存储value
  2. 树的所有叶节点构成一个有序链表,可以按照key排序的次序依次遍历全部数据。
2、B+树存储数据

若参数M选择为5,那么每个节点最多包含4个键值对,我们以5阶B+树为例,看看B+树的数据存储
(a) 在空树当中插入5
在这里插入图片描述
(b)继续插入8,10,15
在这里插入图片描述
(c)继续插入16
在这里插入图片描述
(d)继续插入17
在这里插入图片描述
(e)继续插入18
在这里插入图片描述
(f)继续插入6,9,1920,21,22
在这里插入图片描述
(e)继续插入7
在这里插入图片描述

3、B+树和B树的对比

B+ 树的优点在于:

1.由于B+树在非叶子结点上不包含真正的数据,只当做索引使用,因此在内存相同的情况下,能够存放更多的key。
2.B+树的叶子结点都是相连的,因此对整棵树的遍历只需要一次线性遍历叶子结点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层的递归遍历。

B树的优点在于:

由于B树的每一个节点都包含key和value,因此我们根据key查找value时,只需要找到key所在的位置,就能找到value,但B+树只有叶子结点存储数据,索引每一次查找,都必须一次一次,一直找到树的最大深度处,也就是叶子结点的深度,才能找到value

4、B+树在数据库中的应用

在数据库的操作中,查询操作可以说是最频繁的一种操作,因此在设计数据库时,必须要考虑到查询的效率问题,在很多数据库中,都是用到了B+树来提高查询的效率;

在操作数据库时,我们为了提高查询效率,可以基于某张表的某个字段建立索引,就可以提高查询效率,那其实这个索引就是B+树这种数据结构实现的。
未建立主键索引查询
在这里插入图片描述
执行 select * from user where id=18 ,需要从第一条数据开始,一直查询到第6条,发现id=18,此时才能查询出目标结果,共需要比较6次;
建立主键索引查询
在这里插入图片描述
区间查询
执行 select * from user where id>=10 and id<=18 ,如果有了索引,由于B+树的叶子结点形成了一个有序链表,所以我们只需要找到id为12的叶子结点,按照遍历链表的方式顺序往后查即可,效率非常高。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 什么是二叉树? 二叉树是一种树形结构,其中每个节点最多有两个子节点。一个节点的左子节点比该节点小,右子节点比该节点大。二叉树通常用于搜索和排序。 2. 二叉树的遍历方法有哪些? 二叉树的遍历方法包括前序遍历、中序遍历和后序遍历。前序遍历是从根节点开始遍历,先访问根节点,再访问左子树,最后访问右子树。中序遍历是从根节点开始遍历,先访问左子树,再访问根节点,最后访问右子树。后序遍历是从根节点开始遍历,先访问左子树,再访问右子树,最后访问根节点。 3. 二叉树的查找方法有哪些? 二叉树的查找方法包括递归查找和非递归查找。递归查找是从根节点开始查找,如果当前节点的值等于要查找的值,则返回当前节点。如果要查找的值比当前节点小,则继续在左子树中查找;如果要查找的值比当前节点大,则继续在右子树中查找。非递归查找可以使用栈或队列实现,从根节点开始,每次将当前节点的左右子节点入栈/队列,直到找到要查找的值或者栈/队列为空。 4. 二叉树的插入与删除操作如何实现? 二叉树的插入操作是将要插入的节点与当前节点的值进行比较,如果小于当前节点的值,则继续在左子树中插入;如果大于当前节点的值,则继续在右子树中插入。当找到一个空节点时,就将要插入的节点作为该空节点的子节点。删除操作需要分为三种情况:删除叶子节点、删除只有一个子节点的节点和删除有两个子节点的节点。删除叶子节点很简单,只需要将其父节点的对应子节点置为空即可。删除只有一个子节点的节点,需要将其子节点替换为该节点的位置。删除有两个子节点的节点,则可以找到该节点的后继节点(即右子树中最小的节点),将其替换为该节点,然后删除后继节点。 5. 什么是平衡二叉树平衡二叉树是一种特殊的二叉树,它保证左右子树的高度差不超过1。这种平衡可以确保二叉树的查找、插入和删除操作的时间复杂度都是O(logn)。常见的平衡二叉树包括红黑树和AVL树。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值