参考链接
漫画:什么是B-树? 微信公众号——程序员小灰
漫画:什么是B+树?微信公众号——程序员小灰
这两篇漫画属实简明易懂,推荐各位去看一下。
浅谈算法和数据结构: 十 平衡查找树之B树——寒江独钓_博客园
文中的动图转载自这篇博客。
B树(Balance Tree)
首先说明,B-树就是B树,不要读作B减树。
简介
二叉搜索树具有理论上最少的查询和比较次数O(logn),一般来说,会查询O(树高)次。
但是在实际情况中,在磁盘中进行读取的时间损耗会远大于在内存中的进行的比较损耗。
B树设计的目的就是为了降低树高,使树变得矮胖。
为此,B树的每个节点可以存放多个值,每个父节点可以有多个子节点。
特征
一个m阶的B树具有如下特征
- 根结点至少有两个子女。
- 每个中间节点都包含k-1个元素和k个孩子,其中 m/2 <= k <= m
- 每一个叶子节点都包含k-1个元素,其中 m/2 <= k <= m
- 所有的叶子结点都位于同一层。
- 每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划。
查找策略
- 选取以根节点为根的树作为当前子树
- 和当前子树根节点中的所有值比较,如果有相同,查找完成。
- 如果没有,通过值的大小关系选择对应的值域划分,进入对应子树,返回1.
插入策略
依次插入 6 10 4 14 5 11 15 3 2 12 1 7 8 8 6 3 6 21 5 15 15 6 32 23 45 65 7 8 6 5 4
- 插入值的过程必须在叶子节点中进行,首先按查找策略找到叶子节点中对应的位置并进行插入。
- 如果插入后节点值的个数等于阶数(上限),就将节点拆分成两个节点,并将一个中间值递给父节点(以此来维持非叶节点孩子数=值数+1)。
- 如果父节点接收那个值后值的个数等于阶数,重复第二步。
- 当根节点分裂时,树高加一。
删除
- 如果删除的节点是非叶节点,就把后继值(第一个大于等于它的值,一定在叶子上)移过来,然后认为删除这个叶子上的值。
- 如果删除后小于下限
m/2-1
,那么看一下是否有兄弟节点大于m/2-1
,有的话 父亲->自己,兄弟->父亲。 - 如果只有
m/2-1
的兄弟,就把父亲的一个值移动下来,然后和兄弟合并。最后递归父亲。
B+树
特征
一个m阶的B+树具有如下几个特征:
- 有k个子树的中间节点包含有k个元素(B树中是k-1个元素),每个元素不保存数据,只用来索引,所有数据都保存在叶子节点。
- 所有的叶子结点中包含了全部元素的信息,及指向含这些元素记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
- 所有的中间节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。(有不同的定义:少一个)
查找策略
- 选取根节点作为当前节点。
- 通过根节点的值域划分进入对应的子节点。
- 重复第二步,直到进入叶子节点,在叶子节点中搜寻对应值即可。
与B树的功能不同
- 因为非叶节点不存放与真实数据有关的数据,所以相同大小的磁盘页可以容纳更多的节点。
- 因为只有叶子节点存放数据,所以查找时必须查找到叶子节点,查找效率稳定。(当然,平均情况下要比B树慢些)
- 因为叶子节点之间有链接,所以在范围查询时,可以直接从叶子节点向后,而B树需要进行中序遍历。
总结来讲:IO次数更少,查询性能稳定,范围查询简便。
数据库B+树的聚集索引与非聚集索引
使用B+树实现的数据库索引分为两种,聚集索引与非聚集索引。
聚集索引是指,在B+树的叶子节点中直接存放对应的真实数据。
非聚集索引是指,在B+树的叶子节点中只存放指向真实数据的指针。
显然,聚集索引最多只能建立一次,它本身也表示了数据库表的结构。