B树与B+树的基础知识

B树包括:B-Tree,B+Tree,B*Tree

多叉树与B树的区别在于:B树的所有叶子结点,都在统一的高度上

B-Tree和B+Tree常在磁盘中做索引

 

一颗M阶B树T,满足以下条件:

  • 每个结点至多拥有M棵子树
  • 根结点至少拥有两棵子树(  [2, M] )
  • 除了根结点以外,其余每个分支结点至少拥有M/2棵子树  ( [M/2, M] )
  • 所有的叶结点都在同一层上
  • 有k棵子树的分支结点则存在k-1个关键字,关键字按照递增顺序进行排序( 用于后面的二分查找 )
  • 关键字数量满足ceil(M/2)-1 <= n <= M-1 (ceil:向上取整,每个结点存放至少2个至多M-1个关键字)

M阶:表示一个结点最多可以拥有M个子结点

第五点指出非叶子结点的关键字个数 = 指向子结点指针个数 - 1

指针P1指向关键字小于K[1]的子树,指针PM指向关键字大于K[M-1]的子树,P[i]指向关键字属于(K[i-1],K[i])范围的子树

搜索:从根结点开始,对结点内的有序关键字进行二分查找,如果命中则结束,否则进入查询关键字所属范围的子树,重复查找,直到对应的儿子指针为空或已经是叶结点。

由于M/2的限制——

  • 在插入结点时,如果结点已满,需要将结点分裂为两个各占M/2的结点
  • 在删除结点时,需要将两个不足M/2的兄弟结点合并在一起

插入结点:需要分裂,一定是插在叶子结点上

从根结点开始,找插入key的位置

  1. 如果根结点满了,需要进行【根节点裂变】,新建一个根结点,然后进行分裂
  2. 如果插入的结点是非叶结点,如果其孩子结点满了,先进行【子结点裂变】,然后递归下一层,如果不满,直接递归下一层
  3. 如果插入的结点是叶子结点(因为在判断其父结点时已经保证了它不满),直接插入排序

 删除结点:需要合并

从根节点开始查找key,力求找到要删除的key。从根结点开始,我们会找到在当前结点中对应的指针位置idx,它要么代表了要删除的key索引,要么代表了key所在的子结点指针索引(idx)。

如果在当前结点里找不到要删除的key,就一直递归下去,到子结点里查找

如果在当前结点找到了key,又分为四种情况:

  1. 如果当前结点是叶子结点,直接删除(如果结点的关键字个数为0,需要手动释放结点)
  2. 如果当前结点不是叶子结点,当前结点的prev结点关键字个数>=degree,用左节点最大值填充key位置,再删除这个最大值
  3. 如果当前结点不是叶子结点,当前结点的next结点关键字个数>=degree,用左节点最小值填充key位置,再删除这个最小值
  4. 如果不符合上述情况,就进行合并:把key和右子结点数据加入左子结点中,然后删除当前结点的key,修改关键字和指针

 如果搜索到当前结点child = node->chilrends[idx]的个数刚好等于阶数-1ceil(M/2)-1),需要向前驱子结点left = node->chilrends[idx-1]或后驱子结点right = node->chilrends[idx+1]进行借数这是出于对BTree性质的保护,如果刚好要删除的key是child,那该结点的个数不满足性质,不能直接删除,所以借数提前保证了结点的num足以被删除一个key

借数的过程如下:

选择left或right借数,哪个的num大就选哪个,假设right的num更大:把node的数据放到child右边(L下沉到I后面)、把right的的第一个孩子指针放到child最右边(MN放到L下面)、把right的第一个结点放到node当前位置(O上升到原先L的位置)、right所有关键字和孩子指针都往前移一位;

如果left的num是阶数-1,那就需要把left和node->key[idx-1]进行合并;

如果right的num是阶数-1,那就需要把right和node->key[idx]进行合并;

下图所示阶数为3的BTree删除key = B的过程从根节点L开始搜索,idx=0后child结点为F I ,数量刚好等于2(3-1),所以需要借一个数到child最右边,因为这个BTree没有left了,所以只能向right借数,借数流程见上面的绿字,最后再递归到叶子结点,把B删掉。

 B+Tree

B+树同样是一个多叉树,包括根结点、内部结点和叶子结点。

B+树和B树的区别

  1. 每个叶子节点都有一个指针,指向下一个数据,形成一个有序链表
  2. 只有叶子结点有data,其他内部结点、根结点都是索引

B树的查找并不稳定,最好的情况是查询根节点,最坏的情况是查询叶子结点

相同数据量的情况下,B+树比B树有以下优势

  1. IO次数更少
  2. 查询性能稳定
  3. 范围查询更简便
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值