B树详解

由于数据结构的东西涉及到许多的图片啊,流程啊什么的。所以会参考许多网上存在的资料加以总结,我会将参考链接放在文章后面。

B树

B树基本概念

网上的许多资料在讲述数据结构之前都会讲相关的一些符合、说明以及特性什么的都交代清除。在阅读网上资料的时候我发现许多知识点说的都非常的官方,简单来说就是贼难看懂。所以我在记录的时候会将那些难懂的官方内容用通俗的话解释一下,方便我自己的理解。

首先来说,为什么我们要引入B树呢?有二叉树不是很好吗?

存在即合理。所以还是有存在的理由的。B树的时间复杂度与二叉树一样,均为O(logN)。然而B树出现是因为磁盘IO。IO操作的效率很低,那么,当在大量数据存储中,查询时我们不能一下子将所有数据加载到内存中,只能逐一加载磁盘页,每个磁盘页对应树的节点。造成大量磁盘IO操作(最坏情况下为树的高度)。平衡二叉树由于树深度过大而造成磁盘IO读写过于频繁,进而导致效率低下。
  所以,我们为了减少磁盘IO的次数,就你必须降低树的深度,将“瘦高”的树变得“矮胖”。

PS:这里我找到了一个讲述很好的二叉树与B树的比较链接。大家可以阅读以下。

http://m.elecfans.com/article/662237.html

比如下面的图片:

二叉树
B树

二叉树以2为最大基准向下延伸,而B树则没有标准,所以它可以变得矮矮胖胖的。

B 树又叫平衡多路查找树。一棵m阶的B 树 (m叉树)的特性如下

  • B树中所有节点的孩子节点数中的最大值称为B树的阶,记为M(重点

  • 树中的每个节点至多有M棵子树 ---即:如果定了M,则这个B树中任何节点的子节点数量都不能超过M

  • 若根节点不是终端节点,则至少有两棵子树

  • 除根节点和叶节点外,所有点至少有m/2棵子树(上溢)

  • 所有的叶子结点都位于同一层。(比如上面的图片中我没有了11 13 15,那么我12就没有存在的意义了,就需要调整整个树的布局)

下面是我在百科中找到的性质:

image.png

B树的查找操作

查找操作的理解不难。我直接用几张图来阐述一下。

在B树上进行查找和二叉树的查找很相似,二叉树是每个节点上有一个关键子和两个分支。B树上每个节点有K个关键字和K+1个分支。二叉树的查找只考虑向左还是向右走,而B树中需要由多个分支决定。

B树的查找分两步,首先查找节点,由于B树通常是在磁盘上存储的所以这步需要进行磁盘IO操作。第二步是查找关键字,当找到某个节点后将该节点读入内存中然后通过顺序或者折半查找来查找关键字。若没有找到关键字,则需要判断大小来找到合适的分支继续查找。

如下有一个3阶的B树,观察查找元素21的过程:

image.png

第一次磁盘IO:

image.png

第二次磁盘IO:

image.png

这里有一次内存比对:分别跟3与12比对。

第三次磁盘IO:

这里有一次内存比对,分别跟14与21比对

PS:此处参考:http://m.elecfans.com/article/662237.html

由于B树相对于二叉树来说矮胖了许多,所以它所涉及的IO操作也相对少了许多。不过根据我们上面的分析,其在查找数据的时候并没有减少比较次数。但是我们知道,我们在比较数据的时候是在内存中进行的,所以相对来说时间上会更加迅速,几乎可以忽略。

而相同数量的key在B树中生成的节点要远远少于二叉树中的节点,相差的节点数量就等同于磁盘IO的次数。这样到达一定数量后,性能的差异就显现出来了。

这里先放下一个问题,既然我的介数M是自行设定的。那么我们的M如果很小那么会变成类似于二叉树,那么当M很大的时候呢?

我认为当M很大会导致比较次数过多,在当前磁盘空间能容纳的范围下也有可能导致比较次数过多而导致效率降低的情况。

B树的插入

对高度为k的m阶B树,新结点一般是插在叶子层。通过检索可以确定关键码应插入的结点位置。然后分两种情况讨论:
  1、 若该结点中关键码个数小于m-1,则直接插入即可。
  2、 若该结点中关键码个数等于m-1,则将引起结点的分裂。以中间关键码为界将结点一分为二,产生一个新结点,并把中间关键码插入到父结点(k-1层)中
  重复上述工作,最坏情况一直分裂到根结点,建立一个新的根结点,整个B树增加一层。

例如:在下面的B树中插入key:4

image.png

第一步:检索key插入的节点位置如上图所示,在3,5之间;

第二步:判断节点中的关键码个数:
  节点3,5已经是两元素节点,无法再增加(已经 = 3-1)。父亲节点 2, 6 也是两元素节点,也无法再增加。根节点9是单元素节点,可以升级为两元素节点。;

第三步:结点分裂:
  拆分节点3,5与节点2,6,让根节点9升级为两元素节点4,9。节点6独立为根节点的第二个孩子。

最终结果如下图:虽然插入比较麻烦,但是这也能确保B树是一个自平衡的树。

image.png

另一个例子:

image.png

当插入一个关键字60后,节点内的关键字个数超过出了m-1=2,此时必须进行节点分裂,分裂的过程如上图所示。

资源来源参考于:https://blog.csdn.net/z_ryan/article/details/79685072

B树的删除

B树的删除操作相对较为复杂,我看许多文档解释的都十分官方且难懂。所以我准备用更为简单的图来对删除操作的不同情况进行解释。希望大家看完后能够理解。

  • 首先,根据key删除记录,如果B树中的记录中不存对应key的记录,则删除失败。

之后我们需要分一下四种情况来考虑。(下面的例子中以5阶B树为例,介绍B树的删除操作,5阶B树中,结点最多有4个key,最少有2个key)对于删除key的过程来说,对于叶结点和非叶结点其实差别在一个地方,那就是如果当前我们操作的是非叶结点,那么后继key(这里的后继key指最接近当前删除值,且大于当前删除值的值)覆盖要删除的key,然后在后继key所在的子支中删除该后继key。

例如:

a)原始状态

image.png

b)在上述情况下接着删除27。从上图可知27位于非叶子结点中,所以用27的后继替换它。从图中可以看出,27的后继为28,我们用28替换27,然后在28(原27)的右孩子结点中删除28。删除后的结果如下图所示。

image.png

之后我们就把非叶结点的情况转换为了处理叶结点的情况。

此时我们就要分一下几种情况来考虑如何处理叶结点。

  • ①该结点key个数>=Ceil(m/2)-1(上界,例如m=5,那么最后为2),结束删除操作,否则执行下一步。
  • ②该结点key的个数<Ceil(m/2)-1,且兄弟结点key个数>Ceil(m/2)-1,则父结点中的key下移到该结点,兄弟结点中的一个key上移,删除操作结束。

a)紧接上面的例子。

image.png

b)删除后发现,当前叶子结点的记录的个数小于2(<Ceil(m/2)-1),而它的兄弟结点中有3个记录(>Ceil(m/2)-1 当前结点还有一个右兄弟,选择右兄弟就会出现合并结点的情况,不论选哪一个都行,只是最后B树的形态会不一样而已),我们可以从兄弟结点中借取一个key。所以父结点中的28下移,兄弟结点中的26上移,删除结束。结果如下图所示。

image.png
  • ③如果该结点key的个数<Ceil(m/2)-1,且兄弟结点key个数<=Ceil(m/2)-1,那么将父结点中的key下移与当前结点及它的兄弟结点中的key合并,形成一个新的结点。原父结点中的key的两个孩子指针就变成了一个孩子指针,指向这个新结点。

例如:

a)原图为

image.png

b)在上述情况下删除32。

image.png

当删除后,当前结点中只有一个key(个数<Ceil(m/2)-1),而兄弟结点中也仅有2个key(<=Ceil(m/2)-1)。所以只能让父结点中的30下移和这个两个孩子结点中的key合并,成为一个新的结点,当前结点的指针指向父结点。结果如下图所示。

image.png

由于我们移动了父结点中的数据,所以其key值减少,那么我们就要对当前父结点进行考虑。

下面看一个考虑父结点的例子。

a)原图

image.png

b)上述情况下,我们接着删除key为40的记录,删除后结果如下图所示。

image.png

同理,当前结点的记录数小于2(根据情况③),兄弟结点中没有多余key,所以父结点中的key下移,和兄弟(这里我们选择左兄弟,选择右兄弟也可以)结点合并,合并后的指向当前结点的指针就指向了父结点。

image.png

同理,对于当前结点而言只能继续合并了,最后结果如下所示。(根据情况③

image.png

合并后结点当前结点满足条件,删除结束。

此处参考了部分:https://www.cnblogs.com/nullzx/p/8729425.html的内容。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • B树的定义 一棵m阶的B树满足下列条件: 树中每个结点至多有m个孩子。 除根结点和叶子结点外,其它每个结点至少有m...
    文档随手记阅读 13,155评论 0 25
  • 具体讲解之前,有一点,再次强调下:B-树,即为B树。因为B树的原英文名称为B-tree,而国内很多人喜欢把B-tr...
    文哥的学习日记阅读 93,617评论 11 86
  • B树 1.前言: 动态查找树主要有:二叉查找树(Binary Search Tree),平衡二叉查找树(Balan...
    铁甲依然在_978f阅读 1,443评论 0 4
  • 原文链接 B树 1.前言: 动态查找树主要有:二叉查找树(Binary Search Tree),平衡二叉查找树(...
    非典型程序员阅读 1,145评论 0 3
  • 晚上兵哥过生日,喊我一块,加上我女朋友,共三人。点了四个菜,两瓶白酒,我实在不会挑礼物,带了一个小蛋糕。菜剩一大半...
    定云止水_0cc5阅读 164评论 0 0