java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java二叉树、红黑树、B+树

关于Java的二叉树、红黑树、B+树详解

作者:出世&入世

这篇文章主要介绍了关于Java的二叉树、红黑树、B+树详解,能同时具备数组查找快的优点以及链表插入和删除快的优点的数据结构就是树,需要的朋友可以参考下

数组和链表是常用的数据结构,数组虽然查找快(有序数组可以通过二分法查找),但是插入和删除是比较慢的;而链表,插入和删除很快(只需要改变一些引用值),但是查找就很慢,需要从头开始遍历; 那么有没有一种数据结构能同时具备数组查找快的优点以及链表插入和删除快的优点呢,那就是接下来要介绍的——树。

1、二叉查找树

特性:

2、平衡二叉查找树

特性:

调整平衡的基本思想:

当在二叉排序树中插入一个节点时,首先检查是否因插入而破坏了平衡,若破坏,则找出其中的最小不平衡二叉树,在保持二叉排序树特性的情况下,调整最小不平衡子树中节点之间的关系,以达到新的平衡。 所谓最小不平衡子树,指离插入节点最近且以平衡因子的绝对值大于1的节点作为根的子树。

先插入指定节点,记录下当前节点的信息,LH,EH或者RH。

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

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

3、红黑树:

特性:

1、根节点是黑色;

2、每个节点或者是黑色,或者是红色;

3、每个叶子节点是黑色。 [注意:这里叶子节点,是指为空的叶子节点!;

4、如果一个节点是红色的,则它的子节点必须是黑色的,也就是说一个红节点的父节点只能是黑色

5、从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点,也就是说确保没有一条路径会比其他路径长出俩倍;

红黑树(Red Black Tree) 是一种自平衡二叉查找树 红黑树和AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。 二叉平衡树的严格平衡策略以牺牲建立查找结构(插入,删除操作)的代价,换来了稳定的O(logN) 的查找时间复杂度 它虽然是复杂的,但它的最坏情况运行时间也是非常良好的,并且在实践中是高效的: 它可以在O(log n)时间内做查找,插入和删除,这里的n 是树中元素的数目。

红黑树的操作代价:

RBT 效率总结 : 查找效率最好情况下时间复杂度为O(logN),但在最坏情况下比平衡二叉查找树要差一些,但也远远好于二叉查找树。 插入和删除操作改变树的平衡性的概率要远远小于AVL(RBT不是高度平衡的)。因此需要的旋转操作的可能性要小,而且一旦需要旋转,插入一个结点最多只需要旋转2次,删除最多只需要旋转3次(小于AVL的删除操作所需要的旋转次数)。虽然变色操作的时间复杂度在O(logN),但是实际上,这种操作由于简单所需要的代价很小。

红黑树能够以O(log2(N))的时间复杂度进行搜索、插入、删除操作。此外,任何不平衡都会在3次旋转之内解决。这一点是平衡二叉查找树所不具备的。

调整平衡的基本思想:

场景:HashMap TreeSet TreeMap

4、 B树:

设计缘由:

数据库索引是存储在磁盘上的,当数据量比较大的时候,索引的大小可能有十几个G,甚至更多。当我们利用索引查询的时候,能把整个索引全部加载到内存吗?显然不可能,能做的只有逐一加载每一个磁盘页,这里的磁盘页对应着索引树的节点。

如果我们利用二叉查找树作为索引结构,那么最坏(每个节点数据在不同磁盘页上)的情况下,磁盘IO次数等于索引树的高度。 所以,为了减少磁盘IO次数,我们就需要把原本“瘦高”的树结构变得“矮胖”(节点数变少了)。这就是B树的特征之一

B树是一种多路平衡查找树,它的每一个节点最多包含m个孩子,m被称为B树的阶,m的大小取决于磁盘页的大小。——一个节点最多包含一个磁盘页的数据

也就是说,当B树变得矮胖以后,每个节点可以包含多个数据(数据量大小由磁盘页的大小决定),同样的数据,B树比二叉树/红黑树节点少。所以,B树在查询时,磁盘IO次数变少了,从而可以提升查找性能。

特征:

一个m阶的B树具有如下几个特征:

1.根结点至少有两个子女。
2.每个中间节点都包含k-1个元素和k个孩子,其中 m/2 <= k <= m
3.每一个叶子节点都包含k-1个元素,其中 m/2 <= k <= m
4.所有的叶子结点都位于同一层。
5.每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划

场景:

B树主要应用于文件系统以及部分数据库索引,比如著名的非关系型数据MongoDB。 而大部分关系型数据库,比如mysql,则使用B+树作为索引

5、 B+树

B+树是B树的一种变体,但是又有所不同,

特征:

一个m阶的B+树具有如下几个特征:

这里特别要注意有两点:

其一:每个父节点的元素都出现在子节点中,是子节点的最大(或最小)元素;因此所有叶子节点包含了全量元素信息;

其二:每个叶子节点都带有指向下一个节点的指针,形成了一个有序链表;

其三:只有叶子节点带有卫星数据,其余中间节点仅仅是索引,没有任何数据关联,如下图,所谓卫星数据,指的是索引元素所指向的数据记录,比如数据库中的某一行,在B树种,无论中间节点还是叶子节点都带有卫星数据。

设计优势

B+树的好处主要体现在查询性能上,由于B+树的中间节点没有卫星数据,所以同样大小的磁盘页可以容纳更多的节点元素,这就意味着,一次性加载到内存中的节点元素更多,从而使得查询时IO次数也更少。(举个简单的例子,一个磁盘页可以加载B树的100个节点元素,但是可以加载B+树的1000个节点元素,那么对于查找999这个数来说,B数需要10次IO,B+数只需要1次IO)

B+树相对B树的优点:

综合起来,B+树比B树的优势有三个:1、IO次数更少;2、查询性能更佳;3、范围查询简便

场景:Mysql索引

6、红黑树 VS B+树

红黑树的深度比B+树大,当数据量小时,可以把数据完全放到内存中,红黑树的时间复杂度比B树低(不用每次都查到叶子节点),如linux中进程的调度用的是红黑树,Java中HashMap、TreeMap、TreeSet(都在内存中操作)也都是用红黑树实现;

但是,当数据量大时,不能一次性把数据放到内存时,红黑树往往出现由于树的深度过大而造成磁盘IO读写过于频繁,进而导致效率低下;而B树因其读磁盘次数少,具有更快的速度。

到此这篇关于关于Java的二叉树、红黑树、B+树详解的文章就介绍到这了,更多相关Java二叉树、红黑树、B+树内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文