410-B-,B+,B*树

B-树

我们一般叫“B树”,B是Balance平衡的意思。平衡树。
m阶-平衡树 (一个节点有m个地址域,m-1个数据域)
应用场景:文件索引系统的实现。

AVL树:二阶平衡树。一个节点有2个地址域,1个数据域。(左右孩子的高度差是1,0,-1)

B-树,所有叶子节点都在同一层,是非常平衡的一棵树!

在这里插入图片描述
m阶B-树:
最多有m个地址域(即m个孩子),m-1个数据域。
除根节点和叶子节点外,其他节点的孩子至少有一半个数的孩子(比如说有5个孩子,5/2=3,至少有3个孩子)。
除根节点之外的节点的关键字的个数:比如说是5阶的话。
5/2-1=3-1=2<=n<=4,不能到达5,到达5的话节点就要分裂。

B-树的插入操作

在这里插入图片描述
插入的元素数据都是带有顺序排的!
我们插入C,N,G,A,刚开始,只有这1个节点,也称根节点
在这里插入图片描述
我们现在要插入H,位置如下图所示
在这里插入图片描述
满了,此时中间元素是G,要把这个G提到父节点,产生一个父节点
在这里插入图片描述
在这里插入图片描述
为什么说每个节点至少有一半的孩子?
因为满了就要分裂,把中间的元素提到父节点,然后把左右两边分别形成父节点的左孩子,右孩子,此时左右孩子就都有一半。

现在我们要插入的是E,K,Q
在这里插入图片描述
现在我们要插入M,如下图所示,现在已经满了,我们要进行分裂。M应该插在K和N的中间。
所以我们把M这个中间节点提升到父节点当中。
在这里插入图片描述
现在父节点有3个孩子,2个数据域
在这里插入图片描述
叶子节点是绝对在同一层的,是相当绝对平衡的。
现在我们要插入F节点
F比G小,插在ACEF这里。
再插入W,L,T
在这里插入图片描述
现在要插入Z
Z大于M,应该插在M的右孩子。
在这里插入图片描述
右孩子已经满了。分裂。中间元素是T,所以把T提到父节点当中。
N,Q成为T的左孩子,W,Z成为T的右孩子

在这里插入图片描述
一个节点的元素都是排序插入的,而且左孩子的值都小于父节点的值,父节点的值小于其右孩子的值。
现在我们要插入D
D比G小,插在最左孩子中。
在这里插入图片描述

满了。D是中间元素,提到父节点当中。
AC是D的左孩子,EF是D的右孩子,即G的左孩子
现在插入P,R,X,Y

在这里插入图片描述
现在我们要插入S
S大于M,小于T
所以插在M的右孩子中,
在这里插入图片描述

满了,中间元素Q提到父节点当中,但是父节点也满了,
在这里插入图片描述
DGMQT
中间是M,把M提出去,当父节点。
在这里插入图片描述
分裂都是向上分裂的哦。
是非常平衡的。

B-树的删除操作

在这里插入图片描述
依次删除H,T,R,E
在这里插入图片描述我们删除H,因为H无左右孩子,所以直接删除就可以了
删除后,要看这个节点是否满足B树的特征呢
叶子节点的元素数量 必须是:2<=n<=4
因为是5阶B树,满5个元素就要分裂,左右孩子各2个元素
删除H后,还有K,L,所以满足B树的特征
2个是元素的最基本的该有的数量
在这里插入图片描述
我们删除T,这个T有左右孩子的。
所以我们要上移孩子节点中的相近元素(左孩子最右边或者右孩子最左边的元素,哪边元素多,提哪边的)到父节点中去。
我们要把W提到父节点中。
在这里插入图片描述
我们现在要删除R节点。
因为R没有孩子。我们直接删除。
但是这个孩子现在就只有1个元素。所以不满足B树的性质了。
我们要看相邻的左右兄弟是否丰满(丰满就是元素个数要大于2个)
意思是从兄弟借一个。
如果兄弟丰满,则从父亲节点借一个元素来。把父节点的W借过来。然后把兄弟的X放上去父节点里面。

在这里插入图片描述
这样做才是符合排序树的性质的!在这里插入图片描述
就是要1半的数量
现在我们看下面:在这里插入图片描述我们要删除E直接删除E。不满足性质了。然后看相邻兄弟借。但是其相邻兄弟都刚脱贫(就是都只有2个元素)
并不丰满。
谁也借不了。
则该节点与其相邻的一个兄弟节点进行合并成1个新节点,以此来满足B树条件。(跟左边,或者右边都可以)
在这里插入图片描述
父节点D也放下来和ACE合并了,因为有2个孩子,所以要让父节点变为1个元素了。
现在父节点不丰满了,兄弟是刚刚脱贫,也借不了,只能合并

在这里插入图片描述
连接父节点,合并成1个节点
在这里插入图片描述

B-树的磁盘I/O优势和搜索效率

Windows和linux的文件搜索,以及数据库的索引。
都用到了B+树结构。
我们先看看B-树。
系统中的数据搜索:
数据量非常大,所以这些数据都是存储在磁盘上。
为了增加系统的搜索速度,我们一般会给数据创建索引。
创建索引,就是给数据进行排序,然后进行数据搜索就更加快速。
如果想对磁盘上存储的数据进行快速搜索查找需要解决的问题
更少的磁盘I/O,以及更快的搜索速度、算法。
我们在这里采用m阶平衡树。
红黑树不是平衡树。AVL树是平衡树。

假如说,我们有AVL树和300阶的B-树。
在我们操作系统中,管理内存都是按页面page(4K)分配
管理磁盘(电脑的C盘E盘F盘)是按
块block(16K)分配
我们的文件在
磁盘
存储的,从磁盘读1个文件,读4个字节,实际上,操作系统从磁盘是按块来读取的。
内存的单位是字节,管理的页面单位是页面4096字节。
磁盘的最小单位是扇区,一个扇区大小为512字节,16K除以512就是扇区的个数。

假如现在有1千万个索引需要从磁盘中进行读取和搜索,分别采用AVL树和B-树,看看花费是怎么样。
两者都是平衡树。搜索的过程是一样的。但是:
AVL树的高度:logn(log以2为底的n)
B-树的高度:log300n(log以300为底的n)(一个节点存300个数据)
在这里插入图片描述
在这里插入图片描述

如果用AVL树构建平衡二叉树来存储1千万个索引,需要24层节点。一个节点就是存储着一个索引数据,最差情况就是一个节点对应一个磁盘I/O,需要24次磁盘I/O,才找到

如果是用B-树,一般是取300-500阶,节点的大小刚好存储一块磁盘的数据。
操作系统发起一次磁盘I/O,会把这次磁盘I/O的所有数据都记录在块。
300阶,放299个数据。 log以300为底的N,来计算
在这里插入图片描述
也就是3层。
1千万的索引数据,对于一张数据库表来说,是上限了,再大就要分表了,B-树就是3层,最多花费3次磁盘I/O

搜索算法的时间复杂度都是:logn(log以2为底的n)
(进行的就是二分查找)
因为B-树中在每个元素节点里面采用的也是二分搜索算法,在每一层节点都进行二分查找

B+树的理论

数据库在存索引数据的过程:
在这里插入图片描述
读磁盘,磁盘上读数据,是按照块读取的。
图中是3阶的,2个数据域,3个地址域,图中的数字代表索引项(例如学号作为索引)。
关键是数据都在磁盘上,花费更少的磁盘I/O才是最重要的。
我们看B-树的每个节点存储的不仅仅是关键字,就是索引项,还存储着红色的点,这个红色的点代表索引项对应的记录,就是一行的数据。

在这里插入图片描述
每一个节点存储着不同的索引项,离根节点越近,命中更快,搜索最快,但是B-树总共就是3层,搜索是都挺快的。

B+树是B-树的变形树
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
同样的关键字都在叶子节点又出现了1次。
B+树的非叶子节点存放的都是关键字。
如何找到索引项对应的数据,数据都是在叶子节点上放的。
而且红点都在叶子节点(图中未显示)。
非叶子节点是叶子节点的索引,非叶子节点只存索引项,不存数据地址,没有红点。

索引项和数据都出现在叶子节点中。搜索每一个数据所花费的磁盘I/O都是一样的。
叶子节点中,全部的数据都串在一条有序的链表当中,

当我们在进行区间查找的时候,我们不用遍历复杂的B+树,我们直接遍历叶子节点就可以了。

B+树非叶子节点只存索引项,所以存的就多,找的就快,花费的磁盘I/O就少,查询花费的时间都是一样的(而且树的层数低)!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
因为B+树不存储数据地址
在这里插入图片描述

B*树的理论

在这里插入图片描述
B*树是基于B+树的变种
在这里插入图片描述
叶子节点在一个链表上串着。
非叶子节点只存储关键字。

所有的数据和索引项都是在叶子节点上存储着。
它是在非根和非叶节点增加了指向兄弟节点的指针。
分裂:
在这里插入图片描述
左孩子满了,如果兄弟节点有位置,就把元素通过移到兄弟节点那里,节点值和父节点值交换一下。
然后左孩子就有空闲位置了,就可以插入新元素了。
还是搜索树的性质。

B*树分配节点的概率比B+树低。
节点更少,磁盘I/O次数更少。

左孩子满了,如果兄弟也满了
此时,增加1个新节点,从两边节点各拷贝1/3的数据。
在这里插入图片描述
在这里插入图片描述
如果索引的底层采用B*树就更好了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值