BST、B树、B+树、红黑树之间的总结

1介绍:

1.二叉查找树,

相信大家都接触过,二叉查找树的特点就是左子树的节点值比父亲节点小,而右子树的节点值比父亲节点大,如图

640?wx_fmt=png


基于二叉查找树的这种特点,我们在查找某个节点的时候,可以采取类似于二分查找的思想,快速找到某个节点。n 个节点的二叉查找树,正常的情况下,查找的时间复杂度为 O(logn)。

之所以说是正常情况下,是因为二叉查找树有可能出现一种极端的情况,例如

640?wx_fmt=png


这种情况也是满足二叉查找树的条件,然而,此时的二叉查找树已经近似退化为一条链表,这样的二叉查找树的查找时间复杂度顿时变成了 O(n),可想而知,我们必须不能让这种情况发生,为了解决这个问题,于是我们引申出了平衡二叉树

2、平衡二叉树

平衡二叉树就是为了解决二叉查找树退化成一颗链表而诞生了,平衡树具有如下特点

1、具有二叉查找树的全部特性。

2、每个节点的左子树和右子树的高度差至多等于1。

例如:图一就是一颗平衡树了,而图二则不是(节点右边标的是这个节点的高度)

640?wx_fmt=png

640?wx_fmt=png


对于图二,因为节点9的左孩子高度为2,而右孩子高度为0。他们之间的差值超过1了。

于是,通过平衡树,我们解决了二叉查找树的缺点。对于有 n 个节点的平衡树,最坏的查找时间复杂度也为 O(logn)。

3、红黑树

虽然平衡树解决了二叉查找树退化为近似链表的缺点,能够把查找时间控制在 O(logn),不过却不是最佳的,因为平衡树要求每个节点的左子树和右子树的高度差至多等于1,这个要求实在是太严了,导致每次进行插入/删除节点的时候,几乎都会破坏平衡树的第二个规则,进而我们都需要通过左旋右旋来进行调整,使之再次成为一颗符合要求的平衡树。

显然,如果在那种插入、删除很频繁的场景中,平衡树需要频繁着进行调整,这会使平衡树的性能大打折扣,为了解决这个问题,于是有了红黑树,红黑树具有如下特点:

1、具有二叉查找树的特点。

2、根节点是黑色的;

3、每个叶子节点都是黑色的空节点(NIL),也就是说,叶子节点不存数据。

4、任何相邻的节点都不能同时为红色,也就是说,红色节点是被黑色节点隔开的。

5、每个节点,从该节点到达其可达的叶子节点是所有路径,都包含相同数目的黑色节点。

例如下面的图片(注意,图片中黑色的、空的叶子节点没有画出)(图片来自极客时间)

640?wx_fmt=png

正是由于红黑树的这种特点,使得它能够在最坏情况下,也能在 O(logn) 的时间复杂度查找到某个节点。至于为什么就能够保证时间复杂度为 O(logn),我这里就不细讲了,后面的文章可能会讲。

不过,与平衡树不同的是,红黑树在插入、删除等操作,不会像平衡树那样,频繁着破坏红黑树的规则,所以不需要频繁着调整,这也是我们为什么大多数情况下使用红黑树的原因。

不过,如果你要说,单单在查找方面的效率的话,平衡树比红黑树快。

所以,我们也可以说,红黑树是一种不大严格的平衡树。也可以说是一个折中发方案。

4.B树?


B树是一种平衡多路搜索树,他的每个节点可以拥大于等于2个子节点,M路的B树最多能拥有M个子节点,一个节点中有 m 个子节点则存在 m-1 个记录,记录按照递增次序进行排列,叶节点都在同一层上。B树之所以多路(也就是每个节点上可存多个记录)是为了降低高度,路数越多,树高度越低,查询性能也高。但也不能是无限的,否则就退化成有序数组了。
 

å¨è¿éæå¥å¾çæè¿°


退化成有序数组的B树
 

å¨è¿éæå¥å¾çæè¿°
5.B+树?
B+树是在B树基础上进行改造,他的数据都在叶子结点,同时叶子结点之间还加了指针形成一个链表。

å¨è¿éæå¥å¾çæè¿°

Q1.为什么不用二叉查找树作为数据库索引?

二叉查找树,查找到指定数据,效率其实很高logn。但是数据库索引文件有可能很大,关系型数据存储了上亿条数据,索引文件大则上G,不可能全部放入内存中,
而是需要的时候换入内存,方式是磁盘页。一般来说树的一个节点就是一个磁盘页。如果使用二叉查找树,那么每个节点存储一个元素,查找到指定元素,需要进行大量的磁盘IO,效率很低。
而B树解决了这个问题,通过单一节点包含多个data,大大降低了树的高度,大大减少了磁盘IO次数。

 

Q2.B树和二叉查找树的性能对比?

B树包括B+树的设计思想都是尽可能的降低树的高度,以此降低磁盘IO的次数,因为一个索引节点就表示一个磁盘页,页的换入换出次数越多,表示磁盘IO次数越多,越低效。
B树算法减少定位数据所在的节点时所经历的磁盘IO次数,从而加快存取速度。
假设一个节点可以容纳100个值,那么3层的B树可以容纳100万个数据。(根节点100值,第二层可以存储99个节点(k-1),也就是99*100 个值,第三层可以存储
(99*100-1)*100)结果是近似100万个数据。而如果使用二叉查找树,则需要将近20层,也就是进行20次磁盘IO,性能差距如此之大。
如mongoDB数据库使用,单次查询平均快于Mysql(但侧面来看Mysql至少平均查询耗时差不多)。

 

Q3.B+对比B树的优点?

因为B树的每个节点除了存储指向子节点的索引之外,还有data域,因此单一节点存储的指向子节点的索引并不是很多,树高度较高,磁盘IO次数较多,
而B+树单一节点存储的指向子节点的索引更多,B+树空间利用率高,因此B+树高度更低,磁盘IO次数更少,性能更好。
因为B树的中间节点存储了数据,所以整个树的每一层都有可能查找到要查找的数据,查询性能不稳定,
而B+树所有的data都存储在叶子节点,且叶子节点位于同一层,因此查询性能稳定。
B树如果想要进行范围查找,需要频繁的进行二叉树的中序遍历,进行范围查找比较复杂,
B+树要查找的元素都位于叶子节点,且连接形成有序链表,便于范围查找。

 

Q4.B树,B+树使用场景。

B树主要用于文件系统,和部分数据库索引,如文档型数据库mongodb
B+树主要用于mysql数据库索引。

 

Q5.为什么数据库索引不用红黑树而用B+树?

红黑树当插入删除元素的时候会进行频繁的变色与旋转(左旋,右旋),来保证红黑树的性质,浪费时间。
但是当数据量较小,数据完全可以放入内存中,不需要进行磁盘IO,这时候,红黑树时间复杂度比B+树低。
比如TreeSet TreeMap 和HashMap (jdk1.8)就是使用红黑树作为底层数据结构。



6:为什么用B+树存储索引而不用B树?


这也是和业务场景相关的,一般去数据库查询数据,不一定只选一条,很多时候会选多条数据,在查多条情况下,B树需要做局部的中序遍历,可能要跨层访问。而B+树由于所有数据都在叶子结点,不用跨层,同时由于有链表结构,只需要找到首尾,通过链表就能把所有数据取出来了。

7:为什么用B+树做索引?


我们在MySQL中的数据一般是放在磁盘中的,读取数据的时候肯定会有访问磁盘的操作,磁盘中有两个机械运动的部分,分别是盘片旋转和磁臂移动。盘片旋转就是我们市面上所提到的多少转每分钟,而磁臂移动则是在盘片旋转到指定位置以后,移动磁臂后开始进行数据的读写。那么这就存在一个定位到磁盘中的块的过程,而定位是磁盘的存取中花费时间比较大的一块,毕竟机械运动花费的时候要远远大于电子运动的时间。当大规模数据存储到磁盘中的时候,显然定位是一个非常花费时间的过程,但是我们可以通过B树进行优化,提高磁盘读取时定位的效率。

为什么B类树可以进行优化呢?我们可以根据B类树的特点,构造一个多阶的B类树,然后在尽量多的在结点上存储相关的信息,保证层数尽量的少,以便后面我们可以更快的找到信息,磁盘的I/O操作也少一些,而且B类树是平衡树,每个结点到叶子结点的高度都是相同,这也保证了每个查询是稳定的。

一般去数据库查询数据,不一定只选一条,很多时候会选多条数据,在查多条情况下,B树需要做局部的中序遍历,可能要跨层访问。而B+树由于所有数据都在叶子结点,不用跨层,同时由于有链表结构,只需要找到首尾,通过链表就能把所有数据取出来了。

8:为什么用B+树不用红黑树?


总的来说,B/B+树是为了磁盘或其它存储设备而设计的一种平衡多路查找树(相对于二叉,B树每个内节点有多个分支),与红黑树相比,在相同数据情况下,一颗B/B+树的高度远远小于红黑树的高度,这样在磁盘查找数据时,磁臂定位次数也就越少,查询效率越高。B/B+树上操作的时间通常由存取磁盘的时间和CPU计算时间这两部分构成,而CPU的速度非常快,所以B树的操作效率取决于访问磁盘的次数,关键字总数相同的情况下B树的高度越小,磁盘I/O所花的时间越少。

9:既然hash比B+树快,为什么MySQL数据库要用B+树存储索引?


如果只选一个数据,那确实是hash更快。但是数据库中经常会选择多条,这时候由于B+树索引有序,并且又有链表相连,它的查询效率比hash就快很多了。
而且数据库中的索引一般是在磁盘上,数据量大的情况可能无法一次装入内存,B+树的设计可以允许数据分批加载,同时树的高度较低,提高查找效率。

参考
https://blog.csdn.net/qq_36183935/article/details/81095212
https://mp.weixin.qq.com/s/rDCEFzoKHIjyHfI_bsz5Rw
https://mp.weixin.qq.com/s/jRZMMONW3QP43dsDKIV9VQ
https://blog.csdn.net/zhangshk_/article/details/83013482

https://blog.csdn.net/qq_36533951/article/details/84991777

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章