B-Tree又叫作B树,和平衡二叉树不一样的地方在于B树是多叉树(平衡多路查找树),Oracle和MongoDB的索引技术就是基于B树的数据结构,B树也能够看做是对2-3查找树的一种扩展。面试
一个m阶的B-Tree有如下性质数据库
咱们以查找13为例子:设计模式
第一次磁盘IO:定位到比17小,选择最左子树;数据结构
第二次磁盘IO:定位到比12大,选择最右子树;post
第三次磁盘IO:定位到13,查出对应的数据后,查找结束。学习
对于一个m阶B树,新节点通常是插在叶子层,可是须要根据实际的状况考虑是否须要裂变。设计
1.若该节点中关键码个数小于m-1,则直接插入;指针
2.若该节点中关键字个数等于m-1,则将进行分裂,以中间关键字为界点将节点一分为2,产生一个新的节点,并把中间那个关键字插入到父节点中,继续判断父节点的关键字个数是否等于m-1,依次判断是否分裂,最坏状况下可一直分裂到根节点,整个树增长一层。blog
B树的删除也很是复杂排序
若是关键字所在节点的原关键树>=(m/2),说明删除后仍可知足B树的结构,能够直接干掉。
若是被删除后再也不知足B树的结构,则须要必定的调整过程:
若是其左右兄弟节点中有多余的关键字,即与该节点相邻的节点中关键字的数目大于(m/2)-1,就会将兄弟节点中的最大(左兄弟)或者最小(右兄弟)移到夫节点上,而后将双亲节点中小于(右兄弟的上移)或者大于(左节点上移)关键字的关键字下移到被删关键字的节点中。
若是其左右兄弟都没有多余关键字的时候,状况将变得很是很是复杂;需把删除关键字节点与其左(或者右)兄弟节点中的关键字合并到(父节点指向该删除关键字节点的左(右)兄弟节点的指针)所指向的兄弟节点中去,若是所以父节点中的关键字个数小于规定值,则须要对父节点作一样的处理,最坏状况下会使得整个树减小一层。
B树相对于平衡二叉树的不一样是,每一个节点包含的关键字增多了,特别是在B树应用到数据库的时候,数据库充分利用了磁盘块的原理(磁盘数据存储是采用块的形式存储的,每一个块的大小为4K,每次IO进行数据读取时,同一个磁盘块的数据能够一次性读取出来)把节点大小限制和充分使用在磁盘块大小范围;把树的节点关键字增多后树的层级比原来的二叉树少了不少,大大减小了数据查找和比较的次数,提升了效率。
B+Tree中若是有N个关键字则会拥有n个分支,而B树中n个关键字的节点包含n+1个分支。
B+Tree中,每一个非根节点中的关键字个数是>=(m/2)且<=m,而B树是>=(m/2)-1且<=(m-1)。
B+Tree中根节点的关键字个数是>=1且<=m,而B树是>=1且<=(m-1)。
B+树是B树的一个升级版,由于B+Tree非叶子节点不存储关键字记录的指针,因此其相对于B树来讲B+树更充分的利用了节点的空间,让查找速度更加稳定,其速度彻底接近于二分查找。
\1. B+树的非叶子节点不对关键字记录的指针进行保存,只进行数据索引,使得B+树非叶子节点能保存关键字的能力大大提高,并且树的层级会更少;
2.B+树叶子节点保存了其父节点的关键字记录的指针,因此每次查询必须到叶子节点才能真正获取到相关数据,并且平不少叉树的特色是全部子节点的层级相差不会超过一,因此查询速度相对是很是稳定的;
3.B+Tree树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针;
4.非叶子节点的子节点树=关键字数。
B+树的查找规格是B树同样,都是按照大小一层一层往下,可是不一样点在于其必定会执行到叶子节点,由于只有叶子节点才会存储数据的指针。
插入操做所有在叶子节点中进行
1.若为空树,建立一个叶子节点,而后将记录插入,同时这个叶子节点也是根节点;
2.若被插入的关键字所在的节点,其含有的关键字数目小于m,则直接插入;
3.若被插入关键字所在的节点的关键字数等于m的时候,则须要分裂为两个节点,并将m/2的关键字上移到父节点中,同时判断父节点的关键字个数是否大于m,若是须要分裂继续按照上面的流程进行分裂。
1.若是要删除关键字所在节点的关键字个数,若是大于m/2,直接删除便可;
2.当删除关键字所在节点的关键字个数等于m/2的时候,若兄弟节点中含有多余的关键字,也可从兄弟节点中借用关键字完成删除操做;
3.若兄弟节点没有多余的关键字,则须要与其余兄弟进行合并;
4.若是合并后致使父节点再也不符合B+树的结构,则须要按照上面的规律进行再次结构的调整;
5.注意B+树的结构(非叶子节点会存储索引信息,叶子节点才会存储数据指针),修改完后还需修改其父节点中的索引值。
\1. B+树的层级更少;
\2. B+树查询速度更加稳定;
3.B+树自然具有排序功能,因为B+树全部的叶子节点数据构成了一个有序链表,在查询范围区间数据的时候会更加方便,数据紧密性很好高;
4.B+树全节点遍历更快:B+树遍历整棵树只须要遍历全部的叶子节点便可,而B树须要对每一层进行遍历,因此B+树更有利于全表扫描;
B*树是B+树的变种,不一样点以下
1.关键字个数限制,B+树初始化的关键字的个数是m/2,而B树的初始化个数是2m/3,因此B树的层级会更少;
2.B+树节点满时就会分裂,而B*树满时会检查兄弟节点是否满,若是兄弟节点没有满的话则会向兄弟节点转移关键字,若是兄弟节点也满了的话则从当前节点和兄弟节点各拿出1/3的数据建立一个新的节点出来。这个特性使得其相对B+树分裂的次数也更少;
3.B*树除了根节点外的非叶子节点也会存储兄弟节点的指针;
B*树对比 B+Tree其初始化的容量更大,存储的关键字更多,层级更少,裂变次数也会更少。
欢迎关注公众号 【码农开花】一块儿学习成长 我会一直分享Java干货,也会分享免费的学习资料课程和面试宝典 回复:【计算机】【设计模式】【面试】有惊喜哦