B树概念理解(学习笔记)
(1)AVL树已经能够较大程度减少树的深度,但是希望有更少的磁盘I/O次数,磁盘I/O代价非常昂贵,并且CPU速度的增长远快于磁盘速度的增长,从而引入了B树。
(2)推荐查看我的上一篇博客(https://blog.csdn.net/weixin_42111859/article/details/104022444),里面有关于AVL树的理解过程
1.m叉树
(1)度为m的树第i层上最多有pow(m,i-1)个节点
(2)节点数=节点度之和+1(可以将节点度看成出边,除了根节点之外,每个节点都被一条出边所指向,出边为有向图中的概念)
(3)高度为h的m叉树节点数最多为(pow(m,h)-1)/(m-1) (通过等比数列求和可以得到)
(4)具有n个节点的m叉树最小高度h=ceil( log( m,n(m-1) )+1 ) (ceil表示向上取整)
我证明一下二叉树情况,m叉树只是一个简单的扩展:
2.B树
子树和关键字:若节点有k个关键字,关键字是递增排序的,那么一定有k+1颗子树,子树限定的是范围,这就相当于x轴上有k的点,由它们可以分割出k+1个范围。即n(关键字)=n(子树)-1
(1)B树满足的条件
-
首先是一颗m叉树
-
除了根节点以外所有非叶节点最少有ceil(m/2)棵子树(ceil表示向上取整)
-
如果根节点不是唯一节点,那么它至少有2棵子树
-
所有叶节点在同一层上,不带有任何信息
-
关键字递增排序,子树所有元素小于右关键字(如果存在),大于左关键字(如果存在)
由[1][2]可得:关键字个数取值范围[ceil(m/2)-1,m-1] 由[4]可得:B树所有节点平衡因子为0
举个例子(3路平衡树)(图中叶节点没有画出,计算机中表示为null就可以):
(2)B树高度范围
1.求下限
高度为h的m叉树节点数最多为(pow(m,h)-1)/(m-1) ,每个节点的关键字个数最多为m-1个,所以关键字总数n<=pow(m,h)-1,可得h>=log( m,(n+1) )
2.求上限
B树叶节点数=总关键字数+1(本人还没有证明出来…)
设f(h)表示高度为h时最少叶节点数,则
B树可以控制较大的对数底数(树的度数)从而降低查找的时间复杂度
(3)B树查找:十分类似于二叉排序树,只不过节点关键字序列是有序的,可以使用二分法查找
(4) B树插入:
1.先查找到符合条件的枝节点,如果枝节点关键字个数为m-1(满了),就需要分裂,否则可以直接插入
对于分裂的情况,举个例子(3叉B树):
对于已满情况插入策略可以总结为:先假插入,寻找中间节点,把中间关键字插入父节点,分裂的两部分连接到中间关键字的左右。如果父节点溢出,再次使用插入策略。
注:如果没有父节点需要构造一个父节点,这样树的深度会增加1,但仍旧完全平衡(所有节点平衡因子都为0)
(5)B树的删除
设关键字最小值min=ceil(m/2)-1
1.如果被删除关键字所在节点是最底层的非叶节点(终端),而且节点关键字数>min,则可以直接删除(最简单的情况),图中举了一个3叉树的例子
2.如果被删除关键字k1所在节点是最底层的非叶节点(终端),但是节点关键字数=min,如果它的兄弟节点有一个关键字数>min,则可以借一个,把右(左)兄弟第一个(最后一个)关键字k2和父亲左(右)关键字k3交换,再把k3转移到被删除关键字k1所在节点,就转化为了情况1,图中举了一个3叉树的例子
3.如果被删除关键字k1所在节点是最底层的非叶节点(终端),但是节点关键字数=min,如果它的兄弟节点关键字数都等于min,出现了不够借的情况。把节点的父亲左(右)关键字和和左(右)关键字合并,图中举了一个3叉树的例子
4.如果被删除关键字所在节点不是终端,它左右子节点关键字个数都是min,先移除节点,然后直接合并两个子节点,合并后的新节点刚好满了,如图所示
5.如果被删除关键字k1所在节点不是终端,它的左(右)子节点关键字数>min,则左(右)子树最大(小)值k2,替换该关键字,然后就转化为了情况1,删除替换后的k1(查找最大(小)值的过程类似于二叉搜索树,向一个方向搜索)
转载请声明出处,谢谢合作