B B+ RBT Tree
B B+ RBT Tree
B树 B+树 红黑树
🌲🌲🌲
B树
B-树就是B树,不是B减树,真tn的low
首先,在了解B树之前,我们要先了解什么是二叉搜索树,二叉搜索树的定义如下
BST
- 左子树节点上的值小于根节点的值
- 右子树节点上的值大于根节点的值
- 左右子树也分别为BST
tips:B-树主要用于文件系统以及部分数据库索引(非关系型数据库MongoDB)
其实,从算法逻辑以及算法时间复杂度而言,BST的查找已经到达了最优性能\(O(\log n)\),但是为什么数据库的索引没有使用二叉搜索树来实现的呢?答案就是我们需要考虑磁盘IO的问题。
在查找的过程中,磁盘最坏IO的次数由树的高度决定的,为了减少磁盘的IO次数,将原本瘦高的树变为矮胖就是B-树的特征之一。
B树是一种多路平衡查找树,每一个节点最多包含k个孩子,k被称之为B树的阶。k的大小取决于磁盘页的大小。
一个m阶B-树的特征
- 根节点至少有两个子女
- 每一个中间节点都包含k-1个元素和k个孩子,其中$ m/2 <= k <= m$
- 每一个叶子节点都包含k-1个元素,其中\(m/2 <=k <= m\)
- 所有的叶子节点都位于同一层
- 每一个节点中的元素从小到大排列,可点当中的k-1个元素正好是k和孩子包含的元素的值域分划
一个3阶B-树
B-树 查询例子,查询5
在到达红色节点之前都是尽心的磁盘IO,在红色节点内部进行的是内存IO
B-树在查询过程中的比较次数不一定比BST所需要的查询次数少,尤其是当单一节点中的额元素很多的时候,可是相对于磁盘IO,内存中的耗时基本上可以忽略,所以只要树的高度足够低,IO的次数就足够少,就可以提高查询的性能。
B+树
这确实念做B加树🌲
相对于B-树而言,B+树多了以下特征:
- 有k个子树的中间节点包含有k个元素(B-树中有k-1个元素),每一个元素不保存数据,只用于索引,所有的数据都保存在叶子节点
- 所有的叶子节点中包含了全部的元素信息,以及指向含这些元素记录的指针,并且叶子节点本身按照关键字的大小进行排序
- 所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素
卫星数据 : 卫星数据就是索引元素所指向的数据记录。
在B-树中,无论是中间节点还是叶子节点都带有卫星数据
B-树中的卫星数据
在B+树中,只有叶子节点带有卫星数据,其余中间节点仅仅是索引,没有数据关联。
B+树中的卫星数据
B+树查询分析
查询3
在到达红色节点之前,进行的是磁盘IO,到达节点之后,进行的是内存IO
看起来,和B-树的查询差不多,但是有两点不同
- B+树的中间节点没有卫星数据,所以同样大小的磁盘页可以容纳更多的节点元素
- B+树的查询必须最终查询到叶子节点,而B-树只需要找到匹配元素即可
因为上述的不同点2,可以得出B-树的查找性能并不是很稳定。
并且,B+树在范围查找上面是比较优势的。
B+树范围查找[3,11].(B-说的范围查找是使用中序遍历)
应用
B+树主要应用于大部分关系型数据库中例如mysql
B*树
是B+树的变体,在B+树的非根和非叶子结点再增加指向兄弟的指针
RBT Tree
Red Black Tree 红黑树
首先看一下二叉搜索树的缺点:
现在有一个拥有三个节点的二叉搜索树
然后,依次插入7,6,5,4,3
变成了搜索性能很不好的BST,搜索性能几乎变成了线性
红黑树除了拥有BST的特点,还有以下的特征
- 节点是red或者black
- 根节点是black
- 每一个叶子节点都是黑色的空节点(NIL节点)
- 每个红色节点的两个儿子都是黑色节点(从每个叶子到根的所有路径上不能够有两个连续的红色节点)
- 从任意节点到每一个叶子节点的路径都包含相同数目的黑色节点
一棵RBT
RBT的两种调整方法
- 变色
- 旋转
- 左旋转
- 右旋转
应用
- Java中的TreeMap TreeSet
- Java8中的HashMap