带父节点的平衡二叉树_深入理解(二叉树、平衡二叉树、B-Tree、B+Tree )的区别

一、背景


一般说MySQL的索引,都清楚其索引主要以B+树为主,此外还有Hash、RTree、FullText。本文简要说明一下MySQL的B+Tree索引,以及和其相关的二叉树、平衡二叉树、B-Tree,相关的知识网上很多,为了方便自己更快、清楚的了解,文本聚合一些内容以及个人的一些理解。


二、二叉查找树(BST)

(1)概念:
二叉查找树是基于二分查找法来提高数据查找速度的二叉树的数据结构;关于二分查找法的时间复杂度可以看 时间复杂度 O(log n) 意味着什么?。(2)特点
二叉查找树是采用二分查找法把数据按规则组装成一个树形结构的数据,减少无关数据的检索,提升了数据检索的速度;二叉树的数据结构有以下规则:

  • (1)非叶子节点只能允许最多两个子节点存在。
  • (2)每一个非叶子节点数据分布规则为左边的子节点小当前节点的值,右边的子节点大于当前节点的值;即二叉查找树的特点就是任何节点的左子节点的键值都小于当前节点的键值,右子节点的键值都大于当前节点的键值。
    顶端的节点称为根节点,没有子节点的节点我们称之为叶节点。以下图中的圆为二叉查找树的节点,节点中存储了键(key)和数据(data)。

e61a035d4eab2506e910c99a99e0b06c.png

查找结点值的方法就是二分查找法:查找次数就是树的高度。二叉查找树可以任意地构造 如果向一方倾斜的二叉树是不平衡的,查询效率就低了,二叉查找树变成了一个链表。如下图:

08e48c6270dc8de578171481feae6163.png


在上面的2张图中,查找键值为17的数据,第一张图里需要3次IO,第2张图里需要7次IO。原因是二叉查找树变得不平衡了,也就是高度太高了,从而导致查找效率的不稳定。为了解决这个问题,需要保证二叉查找树一直保持平衡,就需要用到平衡二叉树了。


b31d4ca0e6cb76083353b839c85ec6d2.png

9c7c62fd22ab6b5fb990569ce0ecd105.png

本群免费分享学习资料(C/C++,Linux,golang,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,ffmpeg,TCP/IP,协程,DPDK,嵌入式)等。更多的学习资料请加qqun:1106675687。


三、平衡二叉树(AVL)


在满足二叉查找树特性的基础上,如不是空树,任何一个结点的左子树与右子树都是平衡二叉树,并且高度之差的绝对值不超过 1。 类似于:

b395d87af0a9781e46112d4dd7d406c2.png


关于平衡二叉树的可以看 什么是平衡二叉树(AVL)该文章说明,平衡二叉树相比于二叉查找树来说,查找效率更稳定,总体的查找速度也更快。需要注意的是平衡二叉树是每个节点只存储一个键值和数据的。


四、B树(B-Tree)

(1)概念:
B树和平衡二叉树不同,B树属于多叉树又名平衡多路查找树(查找路径不只两个),数据库索引里大量使用者B-Tree和B+Tree的数据结构。(2)特点:

  • (1)排序方式:所有节点关键字是按递增次序排列,并遵循左小右大原则;
  • (2)子节点数:非叶节点的子节点数>1,且<=M
    ,且M>=2,空树除外(注:M阶代表一个树节点最多有多少个查找路径,M=M路,当M=2则是2叉树,M=3则是3叉);
  • (3)关键字数:枝节点的关键字数量大于等于ceil(M/2)-1个且小于等于M-1个(注:ceil()是个朝正无穷方向取整的函数
    如ceil(1.1)结果为2);
  • (4)所有叶子节点均在同一层、叶子节点除了包含了关键字还包含了数据;

最后我们用一个图和一个实际的例子来理解B树(这里为了理解方便我就直接用实际字母的大小来排列C>B>A)

a9e95fd3647944002cf6374d641c6b03.png


图中可以看到BTree的单个节点可以存储多个键值和数据的平衡树。和平衡二叉树相比:
比如要存储海量的数据,因为(平衡)二叉树的每个节点只存储一个键值和数据的,二叉树的节点将会非常多,高度也会及其高,当查找数据时也会进行很多次磁盘IO,查找的效率将会极低,大致的二叉树结构如下:

3fcd52cdd57a3fdc86c0cf1b3397c277.png

为了解决平衡二叉树的这个弊端,需要一种单个节点可以存储多个键值和数据的平衡树(BTree):

28bcc7de682c95cd9b04e128abb36e3d.png


从上图可以看出,B树相对于平衡二叉树,每个节点存储了更多的键值(key)和数据(data),并且每个节点拥有更多的子节点,子节点的个数一般称为阶,上述图中的B树为3阶B树,高度也会很低。 基于这个特性,B树查找数据读取磁盘的次数将会很少,数据的查找效率也会比平衡二叉树高很多。假如我们要查找id=28的用户信息,那么我们在上图B树中查找的流程如下:

  1. 先找到根节点也就是页1,判断28在键值17和35之间,我们那么我们根据页1中的指针p2找到页3。
  2. 将28和页3中的键值相比较,28在26和30之间,我们根据页3中的指针p2找到页8。
  3. 将28和页8中的键值相比较,发现有匹配的键值28,键值28对应的用户信息为(28,bv)。

区别:B树相对于平衡二叉树的不同是:每个节点包含的关键字增多了,特别是在B树应用到数据库中的时候,数据库充分利用了磁盘块的原理(磁盘数据存储是采用块的形式存储的,每个块的大小为4K,每次IO进行数据读取时,同一个磁盘块的数据可以一次性读取出来)把节点大小限制和充分使用在磁盘快大小范围;把树的节点关键字增多后树的层级比原来的二叉树少了,减少数据查找的次数和复杂度。
相同数量的key在B-Tree中生成的节点要远远少于二叉树中的节点,相差的节点数量就等同于磁盘IO的次数。这样到达一定数量后,性能的差异就显现出来了。


五、B+树(B+Tree)

(1)概念
B+树是B树的一个进化,相对于B树来说B+树更充分的利用了节点的空间,让查询速度更加稳定,其速度完全接近于二分法查找。结构如下:

9442713754d26ff7b98c6b37cbf2b9ed.png


为什么说B+树查找的效率要比B树更高、更稳定;我们先看看两者的区别:1.B+树的非叶子节点不保存数据,只进行数据索引(关键字记录的指针),这样使得B+树每个非叶子节点所能保存的关键字大大增加;2.B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样;3.B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针;4.B+树非叶子节点的子节点数=关键字数;(2)特点:
1、B+树的层级更少:相较于B树,B+每个非叶子节点存储的关键字数更多,树的层级更少所以查询数据更快;
2、B+树查询速度更稳定:B+所有关键字数据地址都存在叶子节点上,所以每次查找的次数都相同所以查询速度要比B树更稳定;
3、B+树天然具备排序功能:B+树所有的叶子节点数据构成了一个有序链表,在查询大小区间的数据时候更方便,数据紧密性很高,缓存的命中率也会比B树高。
4、B+树全节点遍历更快:B+树遍历整棵树只需要遍历所有的叶子节点即可,而不需要像B树一样需要对每一层进行遍历,这有利于数据库做全表扫描。
B树相对于B+树的优点是:如果经常访问的数据离根节点很近,而B树的非叶子节点本身存有关键字其数据的地址,所以这种数据检索的时候会要比B+树快。根据上图我们来看下B+树和B树有什么不同:

  1. B+Tree 非叶子节点上是不存储数据的,仅存储键值,数据存储在同一层的叶节点,而B-Tree节点中不仅存储键值,也会存储数据。之所以这么做是因为在数据库中页的大小是固定的,innodb中页的默认大小是16KB。如果不存储数据,那么就会存储更多的键值,相应的树的阶数(节点的子节点树)就会更大,树就会更矮更胖,如此一来我们查找数据进行磁盘的IO次数有会再次减少,数据查询的效率也会更快。另外,B+Tree的阶数是等于键值的数量的,如果B+Tree一个节点可以存储1000个键值,那么3层B+树可以存储1000×1000×1000=10亿个数据。一般根节点是常驻内存的,所以一般我们查找10亿数据,只需要2次磁盘IO。
  2. 因为B+Tree索引的所有数据均存储在叶子节点,而且数据是按照顺序排列的。那么B+树使得范围查找,排序查找,分组查找以及去重查找变得异常简单。而B-Tree 因为数据分散在各个节点,要实现这一点是很不容易的。

B+Tree 中各个页之间是通过双向链表连接的,叶子节点中的数据是通过单向链表连接的。
其实上面的B-Tree也可以对各个节点加上链表。其实这些不是它们之前的区别,是因为在mysql的innodb存储引擎中,索引就是这样存储的。也就是说上图中的B+Tree索引就是innodb中B+Tree索引真正的实现方式,准确的说应该是聚集索引。
通过上图可以看到,在innodb中,数据页之间通过双向链表连接以及叶子节点中数据之间通过单向链表连接的方式可以找到表中所有的数据。
注意:MyISAM中的B+树索引实现与innodb中的略有不同。在MyISAM中,B+树索引的叶子节点并不存储数据,而是存储数据的文件地址。


六、总结


B+Tree 结构是从二叉查找树,平衡二叉树和B-Tree这三种数据结构演化来的,他们之前的区别上面已经介绍过,现在大致的总结下,如下:
1,二叉查找树是基于二分查找法来提高数据查找速度的二叉树的数据结构,减少无关数据的检索,提升了数据检索的速度。非叶子节点只能允许最多两个子节点存在,每一个非叶子节点数据分布规则为左边的子节点小当前节点的值,右边的子节点大于当前节点的值,每个节点只存储一个键值和数据的。
2,平衡二叉树满足二叉查找树特性的基础上,如不是空树,任何一个结点的左子树与右子树都是平衡二叉树,并且高度之差的绝对值不超过 1。
3,B-TreeB和平衡二叉树不同,B-Tree属于多叉树又名平衡多路查找树, B-Tree相对于平衡二叉树,每个节点存储了更多的键值(key)和数据(data),并且每个节点拥有更多的子节点。
4,B+Tree和B-Tree不同,B+Tree在非叶子节点上,不保存数据,只存储指针,能存储更多的键值,相应的树的阶数(节点的子节点树)就会更大,树就会更矮更胖,如此一来我们查找数据进行磁盘的IO次数有会再次减少,数据查询的效率也会更快。并且B+树索引的所有数据均存储在叶子节点,而且数据是按照顺序排列的。那么B+树使得范围查找,排序查找,分组查找以及去重查找变得异常简单。


首先恭喜您,能够认真的阅读到这里,如果对部分理解不太明白,建议先将文章收藏起来,然后对不清楚的知识点进行查阅,然后在进行阅读,相应你会有更深的认知。如果您喜欢这篇文章,就点个赞或者【关注我】吧!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/487000.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2020年中国新基建人工智能产业链全景图深度分析汇总(附完整企业名单)

来源&#xff1a;北京物联网智能技术应用协会“新基建”是与传统基建相对应&#xff0c;结合新一轮科技革命和产业变革特征&#xff0c;面向国家战略需求&#xff0c;为经济社会的创新、协调、绿色、开放、共享发展提供底层支撑的具有乘数效应的战略性、网络型基础设施。其中“…

Word设置子标题跟随上级标题变化

1 先看看结果吧&#xff0c;结果可实现子标题跟随上级标题变动 2 设置各级标题 2.1 对于1级标题-“标题1”&#xff0c;修改标题样式样式基准&#xff1a;“正文”格式&#xff1a;段落&#xff1a;大纲级别&#xff1a;1级2.2 对于2级标题-“标题2”&#xff0c;修改标题样…

2压缩备份数据库_MySQL数据库备份

前端监控&#xff1a;www.webfunny.cn &#xff1b;只需要简单几步&#xff0c;就可以搭建一套属于自己的前端监控系统&#xff0c;快来试试吧。(github&#xff1a;webfunny_monitor)一、mysqldump 简介mysqldump 是 MySQL 自带的逻辑备份工具。它的备份原理是通过协议连接到 …

人工智能和物联网:智慧城市的交通管理

来源&#xff1a;帮尼资讯当今的智慧城市由不断重塑城市地区的先进技术提供发展驱动力。人工智能和物联网对于世界的运作越来越不可或缺。基于云的服务、物联网、分析平台和许多AI工具正在改变城市居民与环境互动和在环境中出行的方式。纽约市AI咨询和开发机构Blue Orange Digi…

Linux 计划任务

1.计划任务&#xff1a;at一次性计划任务。 &#xff08;1&#xff09;/etc/init.d/atd status   #查看at命令是否开启。 &#xff08;2&#xff09;yum -y install at     #安装at命令 命令&#xff1a; # 一次性计划任务。命令&#xff1a;at 09:14 /回车    at&g…

李德毅院士:基于驾驶脑的智能驾驶车辆硬件平台架构

来源&#xff1a;中国工程院院刊转自&#xff1a;智车科技导 读&#xff1a; 智能驾驶车辆试验平台是人工智能科学、认知科学、控制科学等多个学科领域的最新理论与实践的成果&#xff0c;也是研究智能驾驶理论与技术的基础。不同智能驾驶试验平台的传感器型号、数量、安装位置…

jdk+Tomcat环境搭建

jdk安装与环境变量配置测试Java是否安装好&#xff0c;可以利用cmd命令提示符进行测试。在界面中输入Java&#xff0c;然后回车&#xff1b;得到下图所示的内容&#xff0c;说明安装成功了&#xff0c;可以进行环境变量配置了。进行环境变量配置&#xff0c;首先新建环境变量&a…

有关博弈人机混合智能的再思考

来源&#xff1a;人机与认知实验室【博弈智能研究是一个领域&#xff0c;不是一个学科&#xff0c;我们必须要用不同的方法论&#xff0c;从不同的角度来研究游戏&#xff0c;方法论、角度越多&#xff0c;博弈智能研究就会做得越好。】博弈智能是一种涉及感性&#xff08;尤其…

邬贺铨:工业互联网的网络技术

来源&#xff1a;工业互联网产业联盟在2020工业互联网大会开幕式上&#xff0c;中国工程院院士邬贺铨发表题为《工业互联网的网络技术》的主旨演讲&#xff0c;从工业互联网物理层技术、链路层技术、网络层技术三个方面&#xff0c;对现有通信网络如何满足工业互联网高速发展要…

无返回值_只需一步,在Spring Boot中统一Restful API返回值格式与处理异常

统一返回值在前后端分离大行其道的今天&#xff0c;有一个统一的返回值格式不仅能使我们的接口看起来更漂亮&#xff0c;而且还可以使前端可以统一处理很多东西&#xff0c;避免很多问题的产生。比较通用的返回值格式如下&#xff1a;public class Result { // 接口调用成功或者…

什么是边缘计算(Edge AI)?

来源&#xff1a;万物智能视界边缘AI发源于边缘计算。边缘计算也称为边缘处理&#xff0c;是一种将服务器放置在本地设备附近网络技术, 这有助于降低系统的处理负载&#xff0c;解决数据传输的延迟问题。这样的处理是在传感器附近或设备产生数据的位置进行的&#xff0c;因此称…

VUE全局api

一、什么是全局API&#xff1f; 全局API并不在构造器里&#xff0c;而是先声明全局变量或者直接在Vue上定义一些新功能&#xff0c;Vue内置了一些全局API&#xff0c;比如我们今天要学习的指令Vue.directive。说的简单些就是&#xff0c;在构造器外部用Vue提供给我们的API函数来…

美国运通使用AI技术检测欺诈行为 增强安全性

来源丨Forbes编译丨科技行者多年以来&#xff0c;美国运通一直是人工智能与认知技术领域的领导者。作为坐拥有庞大忠实客户群体的全球金融服务机构&#xff0c;保障客户账户安全一直是运通职能的重中之重。在很长一段时间里&#xff0c;发现并制止欺诈行为一直是美国运通公司的…

未来趋势?通过无线技术管理汽车电池,可消除90%物理布线

电动汽车的电池寿命要求远比手机电池要高。来源 | 雷锋网作者 | 伍文靓雷锋网按&#xff0c;当智能手机中的电池损耗殆尽&#xff0c;无法满足正常使用的续航体验时&#xff0c;用户往往会选择换一台新的设备&#xff0c;以此来解决问题。这是十分常规的操作。然而&#xff0c…

RF MEMS开关时代将开启?

来源&#xff1a;内容编译自「IEEE」&#xff0c;谢谢。二十年前&#xff0c;专门研究射频电路的工程师设想了一种“理想的开关”。这种开关“打开”时&#xff0c;它将具有超低电阻&#xff0c;“关闭”时将具有超高电阻等等。它体积小巧&#xff0c;快速&#xff0c;易于制造…

3dmax体积雾渲染不出来_【扮家家云渲染效果图】3Dmax体积光制作丛林光束|干货教程...

首先打开场景文件场景中创建了一些树木组成了森林的效果。首先要为场景创建灯光。单击创建&#xff0c;选择灯光&#xff0c;将类型切换为标准。接着单击目标平行光。在场景中拖拽进行创建&#xff0c;创建一盏目标平行光&#xff0c;然后单击修改&#xff0c;勾选阴影&#xf…

干货 | 机器人视觉三维成像技术全解析

来源&#xff1a;机器人创新生态在工业4.0时代&#xff0c;国家智能制造高速发展&#xff0c;传统的编程来执行某一动作的机器人已经难以满足现今的自动化需求。在很多应用场景下&#xff0c;需要为工业机器人安装一双眼睛&#xff0c;即机器人视觉成像感知系统&#xff0c;使机…

python海龟绘图_Python教学案例|海龟绘图三例

说明&#xff1a;海龟绘图网上的案例非常多&#xff0c;网上百度一搜就可以找到各种各样的不同绘图参考代码&#xff0c;简单的有&#xff0c;难的有绘制梵高画、九大行星图等等&#xff0c;有需求的最好问度娘&#xff0c;简单又方便。分享Python 基础教程:https://www.runoob…

后香农时代,华为提出10大数学挑战问题

来源&#xff1a;机器之心编辑&#xff1a;杜伟后香农时代的通信技术会如何发展&#xff1f;又有哪些值得业界关注的数学问题呢&#xff1f;在上月底结束的长沙「数学促进企业创新发展论坛」上&#xff0c;华为董事、战略研究院院长徐文伟抛出了后香农时代信息产业发展面临的了…

Oracle中如何查询一个表的所有字段名和数据类型

Oracle中如何查询一个表的所有字段名和数据类型 查询语法 select A.COLUMN_NAME,A.DATA_TYPE from user_tab_columns A where TABLE_NAME表名 查询例子 select A.COLUMN_NAME,A.DATA_TYPE from user_tab_columns A where TABLE_NAMEPUB_GOODS 添加排序后例子 select A.COLUMN…