B树的定义
B树也叫B-树,是一棵多路平衡查找树。B即Balance。
下面,我们看着图,先搞清楚它的定义:
一个结点的最大孩子个数称为树的阶,通常用m表示。一棵m阶B树要么是空树,要么满足以下定义:
(1)一个结点的结构是:(P0,K1,P1,K2,…,Kn,Pn),其中P为指向子树的指针,K为关键字
(2)对于根结点,如果它本身不是叶子结点,至少拥有 1 个关键字,即至少拥有 2 棵子树
(3)对于除根结点之外的所有结点,至少拥有⌈m/2⌉ 棵子树,即至少拥有 ⌈m/2⌉-1 个关键字
(4)为了满足阶的定义,任何结点最多拥有 m 个子树,即最多拥有 m - 1 个关键字
(5)B树的关键字是有序的,它具有两层含义,一来指向卫星数据,二来作为索引划分区间
B树的查找
还是看图呀!以查找6为栗子:
B树的查找包括两个基本操作: ① 在B树中找结点 ② 在结点中找关键字。
更具体的说,根据指针拿到一个结点,是一次磁盘I/O,即第①个动作是在磁盘上进行的;根据有序关键字查找目标,是一次顺序查找或二分查找,即第②个动作是在内存中进行的。
这时,你是不是已经明白了为什么数据库要使用B树而非二叉搜索树呢?
B-Tree和BST的目的都是查找,查找算法的瓶颈是什么呢?比较的次数。但是,数据库查询的瓶颈是什么呢?磁盘I/O的次数。在内存中比较的时间,在磁盘I/O的时间面前完全可以忽略。况且,B-Tree和BST在比较次数上其实相差无几。
把B-Tree和BST摆在一起不难看出,B-Tree比BST矮胖的多。高度更小,说明磁盘I/O次数越少,自然性能越好!当数据库非常非常非常大时,B树的一个结点就是放在一个磁盘块上的,对于磁盘I/O次数的节省也会到达极致。
B树的插入
B树的插入很简单,看着下面的图很容易学会 >_<
情况一:插入后结点关键字个数仍符合B树定义(最多m-1),则直接插入。
以5阶B树为例,根据定义,一个结点最多有5个子树,4个关键字。
情况二:插入后结点关键字个数不符合B树定义(最多m-1),则插入后还要进行结点分裂。
结点分裂的规则是,根据最中间的关键字将结点分成两个结点,最中间的关键字上升到父结点;如果本次上升导致父结点不满足定义,则继续分裂父结点。
什么?想自己练一练?
结合这道练习题,再多说一点:B树的插入都是插入到叶子结点上的,但是,通过结点分裂和关键字上升,插入的值最终有可能出现在树的任何地方。
B树的删除
B树的删除要复杂一些。但是,跟着下面的图解走一遍,保证你可以学会!
还是用一个5阶的B树举栗子 >_<
删除叶子结点,且删除后仍满足B树定义:直接删除。
删除非叶子结点,都可转化为删除叶子结点:用下一个区间的最小值替换被删除结点。
删除叶子结点,且删除后不再满足B树定义,且兄弟够借:向兄弟借一个,不是直接拿过去,而是带着父结点的关键字一起旋转一下。
删除叶子结点,且删除后不再满足B树定义,且兄弟不够借:与兄弟合并,并且带着父结点的关键字一起合并。
☘️