当前位置: 首页 > news >正文

(JAVA)B树和B+树的实现原理阐述

1. B 树

2-3树中,一个节点最多能有两个key,它的实现红黑树中适用对链接染色的方式去表达这两个key。下面将学习另一种树形结构B树,这种数据结构中,一个节点允许多余两个key的存在。

B树是一种树状数据结构,它能够存储数据、对其进行排序并允许以O(logn)的时间复杂度进行查找、顺序读取、插入和删除等操作

1.1 B 树的特性:

B树种允许一个节点中包含多个key,可以是3个、4个、5个甚至更多,并不确定,需要看具体的实现。

我们选择一个参数 M 来构造一个B树,我们可以把它称作是 M阶 的B树,那么该树具有以下特点:

  • 每个节点最多右M-1个key,并且以升序排列:
  • 每个节点最优能有M个子节点;
  • 根节点至少有两个子节点

在这里插入图片描述

1.2 B树存储数据

若参数 M 选择为5,那么每个节点最多包含4个键值对,我们已5阶B树为例,看看B树的数据存储过程

在这里插入图片描述在这里插入图片描述

1.3 B 树中删除数据

(a)原始状态

在这里插入图片描述

(b)在上图的树中,删除21

在这里插入图片描述

由于删除21后的结点的索引值个数仍然大于2(Math.ceil( 5/2 ) -1 =2),因此删除结束。

(c)接着删除27

从上图可知,由于27是非叶子结点,所以要删除27的话,需要用27的后继替代它。从上图可以看出,27的后继是28,因此我们用28来替代27,再删除原来的28,如下图:

在这里插入图片描述

删除后发现,当前结点(当前结点如上图所示)的索引值个数小于2个,而它的兄弟结点有3个索引值(当前结点还有一个右兄弟,选择右兄弟的话,会出现合并结点的情况,不论选哪一个都可以,只是最后的B树形态会不一样而已),那么就向左兄弟借一个索引值,注意这里的借并非直接从左兄弟结点处拿一个索引值过来,如果是这样的话,就破坏了B树父节点左子树比根结点小,右子树比根结点大的特性了。借是把当前结点的父节点的28下移,然后把左兄弟结点的26上移到父节点,删除结束。如下图:

在这里插入图片描述

(d)在上述情况接着删除32

在这里插入图片描述

在删除32后,当前结点剩下31,即索引值数目小于2。这时候,它的兄弟结点,也仅仅有2个索引值,所以不能向兄弟结点借。那只能够让父结点下移一个值(30),并和兄弟结合合并成一个新的结点,如下图:

在这里插入图片描述

当前结点的索引值个数不小于2 (Math.ceil( 5/2 ) -1 =2),满足条件,删除结束。

(e)接着删除 40:

在这里插入图片描述

当前结点由于索引值小于2,因此需要像父结点借,父结点下移36到当前结点,然后和兄弟结点合并(选择左兄弟或右兄弟都可以,这里我选择了左兄弟),如下图:

在这里插入图片描述

但这时候发现,新的当前结点的索引值个数又小于2了,那么只能向其父结点借了,所以其父结点下移33,然后当前结点和其兄弟结点合并,如下图:

在这里插入图片描述

删除结束。

1.4 B树在磁盘文件中的应用

在我们的程序中,不可避免的需要通过IO操作文件,而我们的文件是存储在磁盘上的。计算机操作磁盘上的文件是通过文件系统进行操作的,在文件系统中就使用到了B树这种数据结构。

1.4.1 磁盘

磁盘能够保存大量的数据,从GB一直到TB级,但是它的读取速度比较慢,因为设计到机器操作,读取速度为毫秒级。

在这里插入图片描述

磁盘由盘片构成。每个盘片有两面,又称为盘面。盘片中央有一个可以旋转的主轴,它使得盘片以固定的旋转速率旋转,通常是5400rpm或者是7200rpm,一个磁盘中包含了多个这样的盘片并封装在一个密封的容器内。盘片的每个表面是由一个组称为磁道同心圆组成的,每个磁道被划分为了一组扇区,每个扇区包含相等数量的数据为,通常是512字节,扇区之间由一些间隙隔开,这些间隙中不存储数据。

1.4.2 磁盘IO

在这里插入图片描述

磁盘用磁头来读写存储在盘片表面的位,而磁头连接到一个移动臂上,移动臂沿着盘片半径前后移动,可以将磁头定位到任何磁道上,这称为寻道操作。一旦定位到磁道后,盘片转动,磁道上的每个位经过磁头时,读写磁头就可以感知到该位的值,也可以修改值。对磁盘的访问时间分为 寻道时间旋转时间以及传送时间

由于存储介质的特性,磁盘本身存取就比主存慢的多,再加上机械运动耗费,因此为了提高效率,要尽量减少磁盘I/O,减少读写操作。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个为止开始,顺序向后读取一定的数据放入内存。这样做的理论依据是计算机科学中著名的局部性原理

  • 当一个数据被用到时,其附近的数据也通常会马上被适用。由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此预读可以提高I/O效率。

页是计算机管理存储器的逻辑块,硬件及操作系统往往将主存和磁盘存储区分割成连续的大小相等的块,每个存储块称为一页(1024个字节或其整数倍),预读的长度一般位页的整数倍。主存和磁盘以页尾单位交换数据。当程序要读取的数据不在主存中时,就会触发一个缺页异常,此时系统会向磁盘发出读盘信号,磁盘会找到数据的起始位置并向后连续读取一页或几页数据载入内存中,任何异常返回,程序继续运行。

件系统的设计者利用了磁盘预读原理,将一个节点的大小设为等于一个页(1024个字节或其整数倍),这样每个节点只需要以此I/O就可以完全载入。那么3层的B树可以容纳1024*1024*1024差不多10亿个数据,如果换成二叉查找树,则需要30层!假定操作系统以此读取一个节点,并且根节点保留在内存中,那么B树在10亿个数据中查找目标值,只需要小于3次硬盘读取就可以找到目标值,但红黑树需要小于30次,因此B树大大提高了IO的操作效率。

2. B+树

B+树是对B树的一种变形树,它与B树的差异在于:

  1. 非叶节点仅具有索引作用,也就是说,非叶子节点只存储key,不存储value;
  2. 树的所有叶节点构成一个有序链表,可以按照key排序的次序遍历全部数据

2.1 B+树存储数据

若参数M选择为5那么每个节点最多包含4个键值对,我们以5阶B+树为例,看看B+树的数据存储过程

在这里插入图片描述

在这里插入图片描述

2.2 B+树和B树的对比

2.2.1 B+ 树的优点:(存储好,查找具有最坏情况)

  1. 由于B+ 树在非叶子节点上不包含真正的数据,只当作索引使用,因此在内存相同的情况下,能够存放更多的key
  2. B+ 树的叶子节点都是相连的,因此对整棵树的遍历只需要以此线性遍历叶子节点即可。而且由于数据顺序排列并且相连,所以便于区间查找和搜索。而B树则需要进行每一层递归遍历。

2.2.2 B 树的优点:(存储比不过B+树,查找效率稳定)

由于B 树的每一个节点都包含key和value,因此我们根据key查找value时,只需要找到key所在的为止,就能找到value,但B+ 树只有叶子节点存储数据,索引每一次查找,都必须一次一次,一直找到树的最大深度,也就是叶子节点的深度,才能找到value

2.3 B+ 树在数据库中的应用

在数据库的操作中,查询操作可以说时最频繁的一种操作,因此在设计数据库时,必须要考虑到查询的效率问题,在很多数据库中,都是用到了B+树来提高查询的效率

在操作数据库时,我们为了提高查询效率,可以基于某张表的某个字段建立索引,就可以提高查询效率,那其实这个索引就是B+树这种数据结构实现的。

2.3.1 为建立主键索引查询

在这里插入图片描述

执行select * from user where id = 18,需要从第一条数据开始,一直查询到第六条,发现id=18,此时才能查询处目标结果,共需要比较6次。

2.3.2 建立主键索引查询

在这里插入图片描述

2.3.3 区间查询

执行select * from user where id>=12 and id<=18,如果有了索引,由于B+ 树的叶子节点形成了一个有序链表,所以我们只需要找到id为12的叶子节点,按照遍历链表的方式往后查询即可,效率非常高

3. 前置文章

  1. 浅入数据结构 “堆” - 实现和理论
  2. 开始熟悉 “二叉树” 的数据结构
  3. 队列 和 符号表 两种数据结构的实现
  4. 队列的进阶结构-优先队列
  5. 2-3树思想与红黑树的实现与基本原理

4. ES8 如何使用?

快来看看这篇好文章吧~~!!
😊👉(全篇详细讲解)ElasticSearch8.7 搭配 SpringDataElasticSearch5.1 的使用

相关文章:

(JAVA)B树和B+树的实现原理阐述

1. B 树 2-3树中&#xff0c;一个节点最多能有两个key&#xff0c;它的实现红黑树中适用对链接染色的方式去表达这两个key。下面将学习另一种树形结构B树&#xff0c;这种数据结构中&#xff0c;一个节点允许多余两个key的存在。 B树是一种树状数据结构&#xff0c;它能够存储…...

JC系列CAN通信说明

目录 一、CAN协议二、指令格式三、通信接线3.1、一对一通信3.2、组网通信 四、寄存器定义五、指令说明4、读取电源电压5、读取母线电流6、读取实时速度8、读取实时位置10、读取驱动器温度11、读取电机温度12、读取错误信息32、设定电流33、设定速度35、设定绝对位置37、设定相对…...

Ubuntu22——安装并配置局域网文件共享系统Samba

我们将共享目录设置为 /home/takway/share。以下是基于这个新目录的详细步骤&#xff1a; 在Ubuntu上安装并配置Samba 更新系统包列表 打开终端&#xff0c;执行以下命令来确保你的包列表是最新的&#xff1a; sudo apt update安装Samba 安装Samba及其相关工具&#xff1a; sud…...

HTML CSS 基础

HTML & CSS 基础 HTML一、HTML简介1、网页1.1 什么是网页1.2 什么是HTML1.3 网页的形成1.4总结 2、web标准2.1 为什么需要web标准2.2 Web 标准的构成 二、HTML 标签1、HTML 语法规范1.1基本语法概述1.2 标签关系 2、 HTML 基本结构标签2.1 第一个 HTML 网页2.2 基本结构标签…...

Nginx 使用 GeoIP 模块阻止特定国家 IP 地址的最佳实践

一、概述 为什么要阻止特定国家的 IP 地址&#xff1f; 在全球化的互联网上&#xff0c;网站和服务器可能会面对来自不同国家和地区的用户流量。虽然大多数情况下&#xff0c;我们希望网站能为全球用户提供服务&#xff0c;但在某些特定场景下&#xff0c;阻止来自特定国家的…...

vue3 + vite + cesium项目

GitHub - tingyuxuan2302/cesium-vue3-vite: 项目基于 vue3 vite cesium&#xff0c;已实现常见三维动画场&#xff0c;欢迎有兴趣的同学加入共建&#xff0c;官网服务器相对拉胯&#xff0c;请耐心等候...https://github.com/tingyuxuan2302/cesium-vue3-vite/tree/github...

DR模式 LVS负载均衡群集

DR模式 LVS负载均衡群集 部署共享存储关闭防火墙和核心防护下载&#xff0c;开启nfs服务创建共享文件夹和测试用的静态网页文件编辑nfs配置文件发布共享查看共享 配置 tomcat 服务器关闭防火墙和核心防护安装tomcat配置 tomcat 多实例 配置 nginx 服务器关闭防火墙和核心防护配…...

mysql复制表结构和数据

1.实例 #复制一张和test 一摸一样的表结构 CREATE TABLE test_one like test#往复制的表结构中复制数据 INSERT INTO test_one SELECT * FROM test#两者一起使用相当于 cv大法2.总结 完全实现了表结构和数据的复制&#xff0c;但是两条sql 得分两步执行 2.1 复制表结构 #复制…...

MFC扩展库BCGControlBar Pro v35.1新版亮点:改进网格控件性能

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 BCGControlBar专业版 v35.1已全新发布了&#xff0c;这个版本改进网格控件的性能、增强工具栏编辑器功能等。 …...

Python列表操作详解

1 列表的基本概念 在Python中&#xff0c;列表是一种非常常用的数据结构&#xff0c;它可以存储任意类型的元素&#xff0c;并且支持多种操作。下面将详细介绍Python列表的各种操作。 2列表的操作方法 2.1创建列表 Python可以直接使用方括号[]来创建一个空列表。 示例&am…...

畅捷通T+对接聚水潭成功实施案例

在当今竞争激烈的商业环境中&#xff0c;企业数字化转型已成为提升竞争力的关键。广东某实业有限公司的数字化规划&#xff0c;目前财务系统使用的畅捷通T&#xff0c;电商系统使用的聚水潭。目前两个系统数据割裂导致各个部门的协同效率低下。通过借助轻易云数据集成平台&…...

leetcode-312. 戳气球

题目描述 有 n 个气球&#xff0c;编号为0 到 n - 1&#xff0c;每个气球上都标有一个数字&#xff0c;这些数字存在数组 nums 中。 现在要求你戳破所有的气球。戳破第 i 个气球&#xff0c;你可以获得 nums[i - 1] * nums[i] * nums[i 1] 枚硬币。 这里的 i - 1 和 i 1 代…...

程序设计基础I-实验7 函数(编程题)

7-1 sdut- C语言实验—计算表达式 计算下列表达式值&#xff1a; 输入格式: 输入x和n的值&#xff0c;其中x为非负实数&#xff0c;n为正整数。 输出格式: 输出f(x,n)&#xff0c;保留2位小数。 输入样例: 3 2输出样例: 在这里给出相应的输出。例如&#xff1a; 2.00 …...

使用3080ti配置安装blip2

使用3080ti运行blip2的案例 本机环境&#xff08;大家主要看GPU&#xff0c;ubuntu版本和cuda版本即可&#xff09;&#xff1a;安装流程我最后安装的所有包的信息&#xff08;python 3.9 &#xff09;以供参考&#xff08;environment.yml&#xff09;&#xff1a; 本机环境&a…...

vue3组件通信之defineEmits

一、defineEmits是什么&#xff1f; defineEmits 是vue3提供的方法&#xff0c;又称为自定义事件&#xff0c;不需要引入可以直接使用&#xff0c;用于子组件与父组件通信。 二、使用样例 1.父组件代码 代码如下&#xff08;示例&#xff09;&#xff1a; <template>…...

rust gio-rs 挂载 samba 磁盘

linux 使用的 gio 管理工具 这个工具如下 这是 gio 的rust版本 https://crates.io/crates/gio 可以用 rust 语言实现下面所有操作 gio mout 挂载 samba 如下 //https://valadoc.org/gio-2.0/GLib.MountOperation.html pub async fn gio_mount(uri路径:&str, 用户名:Opti…...

幸存者游戏(类)

#include <iostream> #include <graphics.h> #include <stdio.h> #include <conio.h> #include <vector> #include <string> using namespace std; int idx_player_anim 0; const int player_anim_num 6;//这里要把动画帧数定位const i…...

SQL 中UPDATE 和 DELETE 语句的深入理解与应用

在 SQL 中&#xff0c;UPDATE和DELETE语句是用于操作表数据的重要工具&#xff0c;它们允许我们对已存在的数据进行修改和删除。 一、UPDATE 语句 &#xff08;一&#xff09;基本语法 UPDATE语句的基本语法如下&#xff1a; UPDATE table_name SET column1 value1, colum…...

在 Windows 上查找和结束占用特定端口占用程序,并杀死

在 Windows 上查找和结束占用特定端口&#xff08;如 9003&#xff09;的程序&#xff0c;你可以使用以下步骤&#xff1a; 步骤 1&#xff1a;找到占用端口的进程 ID (PID) 打开命令提示符&#xff08;按 Win R&#xff0c;输入 cmd&#xff0c;然后按回车&#xff09;。输…...

sql server尽量避免滥用影响性能的标量函数

相信很多新手学了 函数的用法就不可避免的想把学到的东西用起来&#xff0c;然而这个函数使用却有坑&#xff0c; 在实际用的时候我发现一个简单的计算封装 &#xff0c;不用函数和用函数执行耗时差太多了。 能避免列上进行函数则尽量避免&#xff0c;这是在实际上遇到的坑 &am…...

python画图|二维动态柱状图输出

【1】引言 在前面的学习过程中&#xff0c;已经探索过二维柱状图和三维柱状图的绘制教程&#xff0c;包括且不限于的文章链接有&#xff1a; python画图|水平直方图绘制_绘制水平直方图-CSDN博客 python画图|3D bar进阶探索_ax.bar3d-CSDN博客 此外也学习了动态的直线输出和…...

CocosCreator 快速部署 TON 游戏:Web2 游戏如何使用 Ton支付

在本篇文章中&#xff0c;我们将继续探讨如何使用 Cocos Creator 开发 Telegram 游戏&#xff0c;重点介绍如何集成 TON 支付功能。通过这一教程&#xff0c;开发者将学会如何在游戏中接入 TON Connect&#xff0c;实现钱包连接、支付以及支付后的校验流程&#xff0c;最终为 W…...

生信初学者教程(二十八):单细胞数据标准化

文章目录 介绍加载R包导入数据消除测序深度影响评估细胞周期的影响识别高度可变的特征缩放数据降维聚类输出结果总结介绍 scRNA-seq的标准化是一个重要的预处理步骤,目的是消除技术变异(比如比如测序深度和基因长度等因素),使基因表达和/或样本之间的比较更加可靠。标准化方…...

【OceanBase诊断调优】—— 错误码 5065 和 5066 的区别

适用版本&#xff1a;V2.1.x、V2.2.x、V3.1.x、V3.2.x 5065 与 5066 是两个近似的报错。 OB_ERR_QUERY_INTERRUPTED(-5065): Message: Query execution was interrupted。 含义为执行中断, 例如终端执行 SQL 过程中按 ctrlc 终止 SQL 执行会报 -5065。 OB_ERR_SESSION_INTER…...

Spring Boot RESTful API开发教程

一、RESTful API简介 RESTful API是一种基于HTTP协议的Web API&#xff0c;其设计原则是简单、可扩展、轻量级、可缓存、可靠、可读性强。RESTful API通常使用HTTP请求方法&#xff08;GET、POST、PUT、DELETE等&#xff09;来操作资源&#xff0c;使用HTTP状态码来表示操作结…...

<Rust>iced库(0.13.1)学习之番外:如何为窗口添加初始值?

前言 本专栏是学习Rust的GUI库iced的合集,将介绍iced涉及的各个小部件分别介绍,最后会汇总为一个总的程序。 iced是RustGUI中比较强大的一个,目前处于发展中(即版本可能会改变),本专栏基于版本0.12.1. 注:新版本已更新为0.13 概述 这是本专栏的番外篇,主要介绍一下新…...

Redis:list类型

Redis&#xff1a;list类型 list命令非阻塞LPUSHLRANGELPUSHXRPUSHRPUSHXLPOPRPOPLINDEXLINSERTLLENLREMLTRIMLSET 阻塞BLPOPBRPOP 内部编码ziplistlinkedlistquicklist 几乎每种语言都有顺序表、数组、链表这样的顺序结构&#xff0c;Redis也做出了相应的支持。 如图&#xff…...

政府采购方式有哪些,竞争性谈判和竞争性磋商的区别

政府采购的方式主要包括公开招标、邀请招标、竞争性谈判、竞争性磋商、询价、单一来源采购和框架协议采购等几种。以下是对这些方式的具体介绍&#xff1a; 公开招标 定义&#xff1a;公开招标是指采购单位依法以招标公告的方式邀请不特定的供应商参与投标的采购方式。适用情形…...

【JavaScript】移动色块案例 实现一个可以拖动并且在拖动过程中会自动改变颜色的色块(JS 事件监听器)

移动色块案例 实现一个可以拖动并且在拖动过程中会自动改变颜色的色块。 移动色块&#xff1a;用户可以通过鼠标按住并拖动页面上的红色方块&#xff08;#blocks&#xff09;。当用户按下鼠标左键时&#xff0c;色块开始跟随鼠标的移动而移动&#xff1b;当用户释放鼠标左键时…...

[Linux#62][TCP] 首位长度:封装与分用 | 序号:可靠性原理 | 滑动窗口:流量控制

目录 一. 认识TCP协议的报头 1.TCP头部格式 2. TCP协议的特点 二. TCP如何封装与分用 TCP 报文封装与解包 如何封装解包&#xff0c;如何分用 分离有效载荷 隐含问题&#xff1a;TCP 与 UDP 报头的区别 封装和解包的逆向过程 如何分用 TCP 报文 如何通过端口号找到绑…...