B树和B+树和红黑树

一、B树

粗略定义

B树是二叉树的拓展,相对二叉树,B树的孩子个数被定义为m,通过m-1个关键字key进行分割,例如 第一个结点的key:10 ,那么就把子树分成了小于10的部分和大于10的部分。根节点的右子树, key 14 20 , 就把子树分成了小于14;大于14 且 小于20 ; 大于20 的三个区间。 每个区间再对应一个结点。

在这里插入图片描述

定义规则

对于整棵树来说:

  • 根节点至少1个key,2个子树
  • 整棵树的阶m,规定了每个结点最大的孩子数
  • 为了维护平衡,所有非叶结点至少有 [m/2] 向上取整颗子树。m用于定义子树的最大数量。那么关键字key的个数为 [m/2]-1
  • 所有的叶子结点都在同一层。

第二和第三条规则就限定了每个节点孩子个数和key个数的取值范围。

对于树上的一个结点来说:

  • n表示关键字的个数
  • keys集合:存放了关键字的数组,且满足 k1 < k2 < k3…
  • p集合:存放了孩子的指针数组,p数组个数 = n +1 ,因为两个孩子夹着一个key
查找

假设查找t , 那么从根节点出发,遍历每个结点的keys, 找到第一个 key[i] > t ,的位置,然后递归到 p[i]子树; 如果找到key[i] == t ,那么直接返回 ; 如果找到尽头,那么进入p[n]子树。

插入关键字

假设插入的关键字是 {20,30,50,52,68,70} ,构造一颗m = 3 的三阶B树。
可以算出非叶结点的关键字取值范围:[m / 2] 向上取整 - 1 = 1, m - 1 = 2 。

第一步:在根节点中插入20,30
在这里插入图片描述

第二步:插入50,由于关键字个数大于2,需要进行分裂。
分裂是找到下标为n / 2的key,提到上一层。
转换前

转换后
转换后
第三步:接下去按照正常的思路,插入52,60,变成下面的状态

在这里插入图片描述
很明显50 52 60超过关键字最大值, 因此需要把52提到上一层。而且此时需要调整50 30 52 之间的关系。调整之后变成下面的样子。

在这里插入图片描述

第四步:插入68,70,调整到上一层之后,上层也超过限制,因此分裂是不断向上执行的。
在这里插入图片描述

插入70后,第一次分裂的结果。
在这里插入图片描述
第二次分裂
在这里插入图片描述

删除关键字
第一大类 删除的关键字在叶结点上

令 min = [m / 2 ] - 1 ,表示节点上关键字的最小合法值
1)如果当前keys的个数 > min, 那么直接删除掉关键字
2)如果当前keys <= min ,但是同层的左右兄弟之间存在 keys > min ,就从兄弟之间借结点。例如下图的删除 2
在这里插入图片描述

借过来之后还要调整 5 7 9的相对位置, 下面是删除完并且调整之后的状态。

在这里插入图片描述

3)如果同层的兄弟子树 key的个数 <= min , 那么需要进行结点合并。
例如下面的删除16,那么合并的方式有两种。

在这里插入图片描述

第一种,把父结点的最左边的关键字转移到下一层。效果是这样的

在这里插入图片描述

第二种做法是把父结点的最右边的关键字转移到下一层。效果是这样的。
在这里插入图片描述

第二大类 删除的关键字不在叶结点上

这大类的做法是把关键字转移到叶结点上。
如何交换呢? 交换之前要介绍相邻关键字,它就是当前结点左子树中最大值,和右子树中的最小值。 也就是根节点的前驱、后继。
接着把根节点和前驱或者后继进行交换,那么就转移到了第一类的情况,而且属于第一类的第一种情况。

在这里插入图片描述

二、B+树

广泛用于数据库和文件系统的查找。

在这里插入图片描述

B树B+树的区别

1、具有n个关键字,那么就有n颗子树,即每一个关键字对应一个子树。
2、每个结点的关键字个数n : [m/2] 向上取整 <= n <= m ,根节点 1<= n <= m。因为关键字和子树的个数相等,前面这两则公式也是子树的取值范围。
3、非叶子结点只起索引作用, 叶子结点包含信息。在B树中,所有的结点的key都用于保存值,方便查找;但是在B+树,就只有叶子结点保存值的地址,也就是对应着记录。
4、B+树中有一个单链表,表头的下一位指向做小的关键字,然后在叶子结点串成一个单链表。

查找/遍历过程

B+树的关键字和子树是一一对应的,它表示p[i]对应的子树,关键字最大值为key[i]。
因此假设要查找num,那么就要在结点中找到第一个key[i] > num的位置,然后进入i-1的子树。

三、红黑树

插入删除后,通过调整可以重新变得平衡。

在这里插入图片描述
1、红黑树是一颗平衡二叉搜索树,中序遍历单调不减,同时它的本质是B树,还是个234B树。
2、节点是红色或者黑色
3、根节点是黑色
4、每个叶节点或者叫外部节点(不在树上的,NULL节点,空节点),是黑色的
在这里插入图片描述

5、每个红色节点的两个子节点都是黑色的。(换句话说,红节点不可能是父子关系)
6、从根节点到每个叶子节点的所有路径上的黑色节点个数相等。(也称黑高度)

插入一个节点,必须插入红色节点,这样只影响了条件4,只要再进行调整就能恢复平衡

每个红黑树都有一个对应的B树,是个234树(234个子树)

在这里插入图片描述

3.1 左旋 以父节点为轴,把右子树向左边甩上去,根节点变成左子树

左旋是把以X为中轴,把右子树y,顺时针向左旋转到x的父节点,使y的左子树等于x。而且y原本的左子树称为x的右子树。
在这里插入图片描述

3.2 右旋 以父节点为轴,把左子树向右边甩上去,根节点变成右子树

同时修改相关节点的引用。旋转之后,二叉查找树的属性仍然满足。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值