【B树、B-树、B+、B*树】

目录

  • 一、B-树(即B树)的定义及操作
    • 1.1、定义
    • 1.2、操作
      • 1.2.1、查找
      • 1.2.2、插入
      • 1.2.3、删除
  • 二、B+树的定义及操作
    • 2.1、定义
    • 2.2、操作
      • 2.2.1、查找
      • 2.2.2、插入
      • 2.2.3、删除
  • 三、B*树

一、B-树(即B树)的定义及操作

1.1、定义

B-tree即B树,B是Balanced,平衡的意思,因为B树的原英文名称为B-tree,国内很多人将其译为B-tree,所以B树就是B-树。

磁盘管理系统中的目录管理,以及数据库系统中的索引组织多数都采用B树这种数据结构。

一棵m阶的B树,或为空树,或是满足以下特性的m叉树:

  1. 树中每个结点至多有m棵子树;
  2. 若根结点不是叶子结点,则至少有两棵子树;
  3. 除根之外的所有非终端结点至少有[m/2](向上取整)棵子树;
  4. 所有叶子结点都出现在同一层次上,并且不带信息,通常称为失败结点(失败结点并不存在,指向这些结点的指针为空,引入失败结点是为了便于分析B树的查找性能);
  5. 所有非终端结点最少有[m/2]-1个关键字,最多有m-1个关键字,结点的结构如图所示:
    在这里插入图片描述
    其中,n为结点中关键字的个数,K为关键字,且在这里插入图片描述;P为指向子树根结点的指针,且指针在这里插入图片描述所指子树中所有结点的关键字均小于在这里插入图片描述在这里插入图片描述所指子树中所有结点的关键字均大于在这里插入图片描述
    对任一关键字K而言,在这里插入图片描述相当于指向其左子树,在这里插入图片描述相当于指向其右子树。
    B树具有平衡、有序、多路的特点。
    在这里插入图片描述
    具体实现时,为记录其双亲结点,B树结点的存储结构通常会增加一个parent指针,指向其双亲结点,如图:
    在这里插入图片描述
#define MaxSize 3typedef struct BTnode{int keynum;//结点中关键字的个数,即结点的大小struct BTnode *parent;//指向双亲结点ElemType key[m+1];//关键字向量,0号单元未用struct BTnode *ptr[m+1];//子树指针向量Record *recptr[m+1];//记录指针向量,0号单元未用
}BTnode, *BTree;//B树查找结果类型
typedef struct{BTnode *pt;int i;//1...m,在结点中的关键字序号int tag;//1:查找成功,0:查找失败
}Result;

1.2、操作

1.2.1、查找

算法思想:
将给定值key与根结点的各个关键字进行比较,由于该关键字序列是有序的,所以查找时可采用顺序查找,也可采用折半查找,查找时:

  1. 在这里插入图片描述,则查找成功;
  2. 在这里插入图片描述,则顺着指针在这里插入图片描述所指向的子树继续向下查找;
  3. 在这里插入图片描述,则顺着指针在这里插入图片描述所指向的子树继续向下查找;
  4. 在这里插入图片描述,则顺着指针在这里插入图片描述所指向的子树继续向下查找。
  5. 如果在自上而下的查找过程中,找到了关键字key,则查找成功,如果直到叶子结点也未找到,则查找失败。

1.2.2、插入

思想:针对m阶高度h的B树,插入一个元素时,首先在B树中是否存在,如果不存在,即在叶子结点处结束,然后在叶子结点中插入该新的元素。

  1. 若该结点元素个数小于m-1,则直接插入;
  2. 若该结点元素个数等于m-1,引起结点分裂,以该结点中间元素为分界,取中间元素(若中间元素为两个,则随机选取一个)插入到父结点中;
  3. 重复上述操作,直到所有结点符合B树的规则,最坏的情况是一直分裂到根结点,生成新的根结点,高度增加1。

示例分析:
以5阶B树为例,5阶B树的规则:

  1. 2<=根结点的子树<=5;
  2. 3<=分支结点的子树<=5
  3. 1<=根结点元素个数<=4
  4. 2<=分支结点元素个数<=4
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

1.2.3、删除

首先查找B树中需删除的元素,如果该元素在B树中存在,则将该元素在其结点中进行删除;删除该元素后,首先判断该元素是否有左右孩子结点,如果有,则上移孩子结点中的某相近元素(“左孩子最右边的节点”或“右孩子最左边的节点”)到父节点中,然后是移动之后的情况;如果没有,直接删除。

  1. 某结点中元素数目小于[m/2]-1,则需要看其某相邻兄弟结点是否丰满;
  2. 如果丰满(结点中元素个数大于(m/2)-1),则向父节点借一个元素来满足条件;
  3. 如果其相邻兄弟都不丰满,即其结点数目等于(m/2)-1,则该结点与其相邻的某一兄弟结点进行“合并”成一个结点;
    以5阶B树为例,详细讲解删除的动作:
    如图依次删除依次删除【8】,【20】,【18】,【5】
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

二、B+树的定义及操作

2.1、定义

B+树是应文件系统所需而产生的B树的变形树。
一棵m阶B+树满足以下条件:

  1. 每个结点最多有M个子结点;
  2. 非叶子结点的根结点至少有两个子结点;
  3. 除根结点外的分支结点至少有[m/2]个子结点;
  4. 有k棵子树的非叶子结点有k个关键字,且关键字按照升序排列;
  5. 叶结点在同一层次中。
  6. 所有叶子结点增加一个链接指针链接在一起;
  7. 所有关键字及其映射数据都在叶子结点中出现。
    在这里插入图片描述
    在这里插入图片描述
    优点:
    B+树的插入过程与B树基本类似,区别在于:
  8. 第一次插入两层结点,一层做分支,一层做根;
  9. B+树在分裂时,是将左半部分的数据保留,右半部分的数据放入新建兄弟结点中,并将新建结点中的最小值更新到父结点中。

2.2、操作

2.2.1、查找

若非终端结点上的关键字等于给定值, 并不终止,而是继续向下直到叶子结点。因此,在B+树中,不管查找成功与否,每次查找都是走了一条从根到叶子结点的路径。B+树查找的分析类似于B-树。

B+树不仅能够有效地查找单个关键字,而且更适合查找某个范围内的所有关键字。例如,在B+树上找出范围在[a, b]之间的所有关键字值。 处理方法如下:通过一次查找找出关键字 a, 不管它是否存在,都可以到达可能出现a的叶子结点,然后在叶子结点中查找关键字值等于a或大于a的那些关键字,对千所找到的每个关键字都有一个指针指向相应的记录,这些记录的关键字在所需要的范围。 如果在当前结点中没有发现大于b的关键字,就可以使用当前叶子结点的最后一个指针找到下一个叶子结点,并继续进行同样的处理,直至在某个叶子结点中找到大于b的关键字,才停止查找。

2.2.2、插入

仅在叶子结点上进行插入,当结点中的关键字个数大于m时要分裂成两个结点,它们所含关键字的个数分别为[(m+1)/2] 和 [(m+1)/2]并且,它们的双亲结点中应同时包含这两个结点中的最大关键字。

2.2.3、删除

B+树的删除也仅在叶子结点进行,当叶子结点中最大关键字被删除时,其 在非终端结点中的值可以作为一个 “分界关键字“ 存在。若因删除 而使结点中关键字的个数少于「m/2]时,其和兄弟结点的合 并过程亦和B-树类似。

三、B*树

B*树是在B+树的基础上,在B+树的非根和非叶子结点增加指向兄弟的指针,将结点的利用率从1/2提高到2/3。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/872623.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【c++11】什么情况下需要封装set/get

文章目录 一、平凡类型与非平凡类型什么时候使用set/get1.平凡类型2.非平凡类型 二、构造函数参数较多解决办法1.把所有参数放到一个结构体里面2.使用build设计模式 三、如果构造函数众多&#xff08;参数很多&#xff09;1.模仿make_unique&#xff0c;就地构造2.基于build设计…

Missing script:‘dev‘

场景&#xff1a; npm run dev 原因&#xff1a;没有安装依赖&#xff0c;可用镜像安装&#xff08;详见下图ReadMe 蓝色字体&#xff09;&#xff0c;没安装依赖可从package-lock.json文件是否存在看出&#xff0c;存在则有依赖 解决&#xff1a;

二叉树、B树/B-树

二叉树 在中文语境中,节点结点傻傻分不清楚,故后文以 node 代表 "结点",root node 代表根节点,child node 代表 “子节点” 二叉树是诸多树状结构的始祖,至于为什么不是三叉树,四叉树,或许是因为计算机只能数到二吧,哈哈,开个玩笑。二叉树很简单,每个 no…

useState函数

seState是一个react Hook(函数)&#xff0c;它允许我们像组件添加一个状态变量&#xff0c;从而控制影响组件的渲染结果 数据驱动试图 本质&#xff1a;和普通JS变量不同的是&#xff0c;状态变量一旦发生变化组件的视图UI也会随着变化(数据驱动试图) 使用 修改状态 注意&am…

单链表算法 - 链表分割

链表分割_牛客题霸_牛客网现有一链表的头指针 ListNode* pHead&#xff0c;给一定值x&#xff0c;编写一段代码将所有小于x的。题目来自【牛客题霸】https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70思路: 代码: /* struct ListNode {int val;struct List…

英福康INFICON TranspectorWare v3 RGA软件操作说明

英福康INFICON TranspectorWare v3 RGA软件操作说明

Python一对一辅导答疑|Rust 德国

你好&#xff0c;我是悦创。 下面是答疑内容。 在 Rust 中&#xff0c;方法的调用方式通常取决于它们是如何定义的。在你的例子中&#xff0c;print_drink方法最初是作为一个接受Drink类型实例作为参数的关联函数&#xff08;类似于静态方法&#xff09;定义的。后来&#xff…

供应链管理(SCM):如何在颜值和体验上发力

要在供应链管理系统&#xff08;SCM&#xff09;中在颜值和体验上发力&#xff0c;让用户感觉耳目一新&#xff0c;可以采取以下措施&#xff1a; 界面设计优化&#xff1a; 对供应链管理系统的界面进行优化&#xff0c;注重界面的美观、简洁和易用性。采用现代化的设计风格、…

技能 | postman接口测试工具安装及使用

哈喽小伙伴们大家好!今天来给大家分享一款轻量级,高效好用的接口测试工具-postman. Postman是一个流行的API开发工具&#xff0c;主要用于测试、开发和文档化API。以下是关于Postman的介绍及其主要使用场景&#xff1a; Postman介绍&#xff1a; 1. 功能丰富的API客户端&#…

在SpringCloud中如何轻松实现微服务间的通信

在Spring Cloud中&#xff0c;实现微服务间的通信非常简单。Spring Cloud提供了多种方式来进行微服务之间的通信&#xff0c;包括使用RestTemplate、Feign、Ribbon、Eureka等组件。下面我将详细介绍这些方式的使用方法。 使用RestTemplate进行通信&#xff1a; RestTemplate是S…

django报错(一):python manage.py makemigrations,显示“No changes detected”

执行python manage.py makemigrations命令无任何文件生成&#xff0c;结果显示“No changes detected”。 解决方案一&#xff1a; 1、执行命令&#xff1a;python manage.py makemigrations –empty appname 2、删除其中的0001_initial.py文件&#xff08;因为这个文件内容是…

【docker 部署springboot项目】

一、docker安装 1.检查Linux内核版本高于3.10才可安装 uname -r 2. 卸载旧版本 sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine 3. 使用docker仓库进行安装 安装所需的软…

Qt MV架构-委托类

一、基本概念 与MVC模式不同&#xff0c;MV视图架构中没有包含一个完全分离的组件来处理与用户的交互。 一般地&#xff0c;视图用来将模型中的数据显示给用户&#xff0c;也用来处理用户的输入。为了获得更高的灵活性&#xff0c;交互可以由委托来执行。 这些组件提供了输入…

Python入门------pycharm加载虚拟环境

pycharm虚拟环境配置&#xff1a; 在按照前面的办法&#xff0c;配置好虚拟环境后,如果我们需要到虚拟环境开发&#xff0c;就需要给编译器配置虚拟环境 1.打开编译器&#xff0c;点击右下角的interpreter选项 2. 点击ADD Interpreter,添加虚拟环境 3. 因为我们使用的是原始…

欧式空间、傅里叶级数与希尔伯特空间的解释

欧式空间&#xff08;欧几里得空间&#xff09; 欧几里得几何就是中学学的平面几何、立体几何&#xff0c;在欧几里得几何中&#xff0c;两平行线任何位置的间距相等。 而中学学的几何空间一般是2维&#xff0c;3维&#xff08;所以&#xff0c;我们讨论余弦值、点间的距离、内…

数据库管理的艺术(MySQL):DDL、DML、DQL、DCL及TPL的实战应用(下:数据操作与查询)

文章目录 DML数据操作语言1、新增记录2、删除记录3、修改记录 DQL数据查询语言1、查询记录2、条件筛选3、排序4、函数5、分组条件6、嵌套7、模糊查询8、limit分页查询 集合操作union关键字和运算符in关键字any关键字some关键字all关键字 联合查询1、广义笛卡尔积2、等值连接3、…

【事件排查】网络问题排查H3C无线优化方案

目录 背景 问题一 排查思路 解决方法 问题二 排查思路 解决方法 背景 公司进行搬迁&#xff0c;网络进行了调整 基于上篇文章《H3C Intelligent Management Center无线认证新增设备如何配置》 来做了一些网络配置&#xff0c;公司后续出现以下2个问题&#xff1a; …

在Linux系统安装MySQL有多简单

MySQL 是一种流行的开源关系数据库管理系统&#xff0c;广泛应用于各种类型的应用程序和服务。本文将介绍在 Linux 上安装 MySQL 的多种方式&#xff0c;包括离线安装、使用 Docker 容器、通过 Helm Chart 安装在 Kubernetes 集群中等。 前言 无论你是在开发环境中测试&#…

设计模式-概述*

1.代码的质量的评判 可维护性&#xff1a;不破坏原有代码设计以及不引入新的bug的前提下&#xff0c;能够快速修改或新增代码&#xff1b;可读性&#xff1a;人类能理解的代码&#xff08;编程规范-命名、函数是否冗长、类是否过大等&#xff09;&#xff1b;可扩展性&#xff…

奥运火炬的三次传递 品牌精神的传承赓续丨陈忠伟董事长巴黎传递奥运圣火

7月14号&#xff0c;2024年巴黎奥运火炬在巴黎传递&#xff0c;中国企业家、恒源祥集团董事长兼总经理陈忠伟作为火炬手参与了传递&#xff0c;这也是他第三次参加奥运火炬的传递。 &#xff08;陈忠伟董事长点燃火炬&#xff09; 恒源祥从上世纪80年代起就开始赞助体育赛事&a…