索引的数据结构
二叉树搜索树
缺点:IO操作频繁,最坏的情况:操作IO次数等于树高。
B-树(Balance-Tree,多路平衡查找树)
先解释一下什么是树阶。
对于一个m阶的B-Tree,每个结点至少有m个结点。即最多子节点的个数。
上例中,中间方框中的结点,它的子节点是最多的,有三个,那么这个树就是3阶数(m=3)。
再来看一下B-Tree的特性
- 根结点至少有两个子女。
- 每个中间节点都包含k-1个元素和k个孩子,其中 m/2 <= k <= m
- 每一个叶子节点都包含k-1个元素,其中 m/2 <= k <= m
- 所有的叶子结点都位于同一层。
- 每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划。
逐条解释一下:
- 根节点如果只有一个子女,那就不能叫平衡树了,这个很好理解。
- 这一条分3点解析一下:
- 为什么是k-1个元素和k个孩子?翻译过来就是,作为一个中间节点,它包含的元素永远比子女数少1。如果一个中间节点包含2个元素,那么它应该有3个孩子。原因是有第5条的限制:这2个元素,是对3个孩子包含的元素的值划分。
- .为什么k>=m/2。注意,这里m/2是向上取整。假设有一个3阶树,即m=3,3/2取的值是2,不是1!翻译过来就是,假设有一个3阶数,那么它的中间节点最少有1个元素,2个孩子。如果是一个5阶树,那么中间节点最少有2个元素,3个孩子。为什么要除2呢?大于等于1不可以么?我想不行,实际上也真是不行,因为B-Tree的存在就是为了能减小数的高度,让数据在同一层更紧密一点,不然和二叉树有什么区别。
- 为什么k<=m。这个好解释一点了,如果有k个孩子,说明他是最高阶。
- 为什么叶子节点包含的元素数是阶数-1?我觉得可以理解为没有孩子的中间节点吧。大家可以补充。
- 为什么叶子节点要保持在同一层?一个B树通过约束所有叶子节点在相同深度来保持平衡。
- 这条保证了搜索树的特性。
再举个例子,给出一棵三阶树
- 根节点有两个孩子。
- 中间节点(2,6)有2个元素,有3个孩子(1)(3,5)(8)。中间节点(12)有1个元素,2个孩子(11)(13,15)。
- 叶子节点最多包含2个元素。
- 所有叶子节点都在同一层。
- 看(2,6)节点及其子节点,1<2<3<5<6<8,符合第五条性质。
B+Tree(B+树)
B+树是B树的一种变体,有着更高的查询效率。
B+树的性质:
- 非子节点包含k个元素和k和孩子。
- 每个元素不保存数据,只用来索引,所有数据都保存在叶子结点。
- 所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素
- 所有叶子节点均有一个链指针指向下一个叶子结点。
举个例子看一下
B+树的优势:
- 单一节点存储更多的元素,使得查询的IO次数更少。
- B-树的查询次数不固定,B+树所有查询都要查找到叶子节点,查询性能稳定。
- 在范围查找上,B-树使用中序遍历,B+树所有叶子节点形成有序链表,便于范围查询.
参考连接如下:
https://mp.weixin.qq.com/s/rDCEFzoKHIjyHfI_bsz5Rw
https://mp.weixin.qq.com/s/jRZMMONW3QP43dsDKIV9VQ
https://zh.wikipedia.org/wiki/B%E6%A0%91