热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【数据结构】B树(B树)和B+树

B树的定义B树,又称为多路平衡查

B树的定义

B树,又称为多路平衡查找树,B树中所有结点的孩子个数的最大值称为B树的阶,通常用m表示。一颗m阶B树或为空树,或为满足如下特性的m叉树:
1)树中每个结点至多有m颗子树,即最多含有m-1个关键字。
2)若根结点不是终端节点,则至少有两颗子树。
3)除根节点外的所有非叶结点至少有⌈m/2⌉颗子树,即至少含有⌈m/2⌉-1个关键字。
4)所有非叶结点的结构如下:

np0k1p1k2p2knpn

其中,ki为结点的关键字,且满足k1 【ki若是对应了value,则还需要将value考虑进去】
【B树的非叶结点中保存m-1个关键字,以及其所对应的记录的地址,保存m个指向子树/子结点的指针,保存一个整数n,即记录该节点中实际关键字个数的整数】
5)所有叶结点都出现在同一层次上,并且不带信息(可以视为外部结点或类似于折半查找判定树的查找失败结点,实际上这些结点不存在,指向这些结点的指针为空)。

B树的高度(磁盘存取次数)

对于一颗包含n个关键字、高度为h、阶数为m的B树:

1)因为B树中每个结点最多有m棵子树,m-1个关键字,所以在一颗高度为h的m阶B树中关键字的个数应满足n <= (m-1)(1 + m + m^2 + … + m^h-1) = m^h - 1,因此有:h >= logm(n+1)

2)若让每个结点中的关键字个数达到最少,则容纳同样多的关键字的B树的高度达到最大。由B树的定义:第一层至少有1个结点;第二层至少有两个结点;除了根结点外的每个非终端结点至少有⌈m/2⌉颗子树,则第三层至少有2⌈m/2⌉个结点,第h+1层至少有2⌈m/2⌉^(h-1)个结点,注意到第h+1层是不包含任何信息的叶子结点。
对于关键字个数为n的B树,叶结点即查找不成功的结点为n+1,由此有n+1 >= 2(⌈m/2⌉)^(h-1)
h <= log⌈m/2⌉((n+1)/2) + 1

例如,假设一颗3阶B树共有8个关键字,其高度范围为2 <= h <= 3.17

B树的查找

1)在B树中找结点
2)在结点内找关键字
由于B树常存储在磁盘上,因此前一个查找操作是在磁盘上进行的,而后一个查找操作是在内存中进行的,即在找到目标结点后,先将结点信息读入内存,然后在结点内采用顺序查找或折半查找法。查找到叶结点时(对应指针为空指针),则说明树中没有对应的关键字,查找失败。

B树的插入

1)定位。利用前述的B树查找算法,找出插入该关键字的最低层中的某个非叶结点。
2)插入。在B树中,每个非失败结点的关键字个数都在区间⌈m/2⌉-1到m-1内。插入后的结点关键字个数小于m,可以直接插入;插入后检查被插入结点内的关键字的个数,当插入后的结点关键字个数大于m-1时,必须对结点进行分裂。
分裂的方法:取一个新结点,在插入key后的原结点,从中间位置(⌈m/2⌉)将其中的关键字分为两部分,左部分包含的关键字放在原结点中,右部分包含的关键字放在新结点中,中间位置(⌈m/2⌉)的结点插入原结点的父结点。若此时导致其父结点的关键字个数也超过了上限,则继续进行这种分裂操作,直至这个过程传到根节点为止,进而导致B树高度增1。

B树的删除

当被删除关键字k不在终端结点(最低层非叶结点)中时,可以用k的前驱(或后继)k’来代替k,然后在相应的结点中删除k’,关键字k’必定落在某个终端结点中,则转换成了被删关键字在终端结点中的情形。因此只需讨论删除终端结点中关键字的情形。

当被删关键字在终端节点中时,有下列三种情况:

1)直接删除关键字。若被删除关键字所在结点的关键字个数 ≥ ⌈m/2⌉,表明删除该关键字后仍满足B树的定义,则直接删去该关键字。

2)兄弟够借。若被删除关键字所在结点删除前的关键字个数 = ⌈m/2⌉-1,且与此结点相邻的右(或左)兄弟结点的关键字个数 >= ⌈m/2⌉,则需要调整该结点、右(或左)兄弟结点、及其双亲结点(父子换位法),以达到新的平衡。

3)兄弟不够借。若兄弟不够借时,就将该结点删除,删除完后将兄弟结点和双亲结点进行合并。在合并过程中,双亲结点中的关键字个数会减1。若其双亲结点是根结点且关键字个数减少至0,则直接将根节点删除,合并后的新结点成为根;若双亲结点不是根节点,且关键字个数减少到⌈m/2⌉-2,则又要与它自己的兄弟结点进行调整或合并操作。

B+树的定义

一颗m阶的B+树需满足下列条件:
1)每个分支结点最多有m棵子树(孩子节点)。
2)非叶根节点至少有两棵子树,其他每个分支结点至少有⌈m/2⌉棵子树。
3)结点的子树个数与关键字个数相等
4)所有叶结点包含全部关键字及指向相应记录的指针,叶结点中将关键字按大小顺序排列,并且相邻叶结点按大小顺序相互链接起来。
5)所有分支结点(可以视为索引的索引)中仅包含它的各个子结点(即下一级索引块)中关键字的最大值及指向其子结点的指针。

B+树和B树的差异

1)在B+树中,具有n个关键字的结点含有n棵子树;而在B树中,具有n个关键字的结点至少含有n+1棵子树。
2)在B+树中,每个结点(除根节点外)中的关键字个数n的取值范围为⌈m/2⌉ <= n <= m 。根结点n的取值范围为2 <= n <= m。而在B树中,除根节点外,其他所有非叶子结点的关键字个数n的取值范围是⌈m/2⌉-1 <= n <= m -1,根结点n的取值范围是1 <= n <= m - 1。
3)在B+树中,所有叶子结点包含了全部关键字,即其他非叶子结点中的关键字也包含在叶子结点中;而在B树中,关键字是不重复的。
4)在B+树中,所有非叶子结点仅仅起到了索引的作用,即结点中的每个索引项只包含对应子树的最大关键字和指向子树的指针,不包含该关键字对应记录的存储地址;而在B树中,每个关键字对应一个记录的存储地址。
5)在B+树中有两个头指针,一个指向根节点,另一个指向关键字最小的叶子结点,所有叶子结点链接成一个链表;而在B树中,叶子节点并不会有指针相连。


推荐阅读
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • Monkey《大话移动——Android与iOS应用测试指南》的预购信息发布啦!
    Monkey《大话移动——Android与iOS应用测试指南》的预购信息已经发布,可以在京东和当当网进行预购。感谢几位大牛给出的书评,并呼吁大家的支持。明天京东的链接也将发布。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了游戏开发中的人工智能技术,包括定性行为和非定性行为的分类。定性行为是指特定且可预测的行为,而非定性行为则具有一定程度的不确定性。其中,追逐算法是定性行为的具体实例。 ... [详细]
  • 提升Python编程效率的十点建议
    本文介绍了提升Python编程效率的十点建议,包括不使用分号、选择合适的代码编辑器、遵循Python代码规范等。这些建议可以帮助开发者节省时间,提高编程效率。同时,还提供了相关参考链接供读者深入学习。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • Linux服务器密码过期策略、登录次数限制、私钥登录等配置方法
    本文介绍了在Linux服务器上进行密码过期策略、登录次数限制、私钥登录等配置的方法。通过修改配置文件中的参数,可以设置密码的有效期、最小间隔时间、最小长度,并在密码过期前进行提示。同时还介绍了如何进行公钥登录和修改默认账户用户名的操作。详细步骤和注意事项可参考本文内容。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
author-avatar
破背包
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有