数据结构——B树和B+树

数据结构——B树和B+树

  • 一、B树
    • 1.B树的特征
    • 2.B树的插入操作
    • 3.B树的删除操作
    • 4.B树的缺点
  • 二、B+树
    • B+树的特征

平衡二叉树或红黑树的查找效率最高,时间复杂度是O(nlogn)。但不适合用来做数据库的索引树。

因为磁盘和内存读写速度有明显的差距,磁盘中存储的数据需要先读取到内存中才能进行高速的检索。而数据库当中存储着海量的数据,光是数据库索引就有可能占据几个GB甚至更大的空间。当我们要查找数据的时候,显然不可能把整个索引树读到内存中。因此,我们只能以索引树的节点为基本单元,每次把单一节点从磁盘读取到内存当中,进行后续操作。

如果磁盘当中的索引树是一棵平衡二叉树,查找的时候,在最坏情况下,磁盘I/O的次数等于索引树的高度。

为了减少磁盘I/O,我们需要把原本“瘦高”的树结构变得“矮胖”,让每一个节点承载更多的元素,拥有更多的孩子。

B树和B+树,就是这样的数据结构,因此它们非常适合做数据库和文件系统的索引。

一、B树

1.B树的特征

B树也被称为B-树(中间的横线是一个连接符,不是“B减树”!)

B树单一节点拥有的最多子节点数量,称为B树的“阶”。一个m阶的B树,具有如下几个特征:

  1. 根节点至少有两个子节点。
  2. 每个中间节点都包含k-1个元素(也被称为关键字)和k个孩子,其中m/2 <= k <= m。
  3. 每一个叶子节点都包含k-1个元素,其中m/2 <= k <= m。
  4. 所有的叶子节点都位于同一层。
  5. 每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划。

如图是一个3阶的B树:
在这里插入图片描述

B树的查找过程(以上图中查找5为例):
在这里插入图片描述
B树查询中的比较次数其实不比平衡二叉树少,但是节点内部元素的比较是在内存中进行的,时间成本几乎可以忽略。真正影响性能的,是磁盘I/O的次数,只要树的高度降低,磁盘I/O次数就会相应减少,从而提高整体性能。

2.B树的插入操作

B树的插入操作,首先是在叶子节点进行的,可以分成两种情况:

1)插入元素未改变规则,即叶子节点元素数量不超过m-1

未改变规则,就不用做任何调整。

2)插入元素使叶子节点元素过多,超过m-1个元素
在这里插入图片描述
新插入的元素4使相应的叶子节点元素超过2个,打破了3阶B树的规则。于是,需要进行节点的“分裂”,把节点m/2位置的元素上升到父节点,剩余的左半边元素和右半边元素分成两个独立的叶子节点:
在这里插入图片描述

此时,父节点(2,4,6)的元素同样超过了2个,我们继续对父节点
进行分裂,元素4上升到祖父节点:
在这里插入图片描述

这一次并没有打破B树的规则,插入调整完毕。

3.B树的删除操作

分为4种情况:

1)删除元素在叶子节点,未改变规则

没有打破B树的规则,因此不用做任何调整。

2)删除元素在叶子节点,剩余元素不足,相邻兄弟节点有多余元素
在这里插入图片描述

如图所示,删除叶子节点的元素8之后,该节点少于1个元素。此时可以向左侧兄弟节点“借调”一个元素过来。但元素5不能直接放到元素8的位置,需要上升到父节点当中,再把元素5和8之间的元素6移动到元素8的位置:
在这里插入图片描述
3)删除元素在叶子节点,剩余元素不足,相邻兄弟节点没有多余元素
在这里插入图片描述
如上图所示,删除叶子节点的元素3之后,该节点少于1个元素,左右兄弟也没有多余的节点可以借调。此时我们可以把相邻叶子节点“合并”。删除的元素3和右侧相邻节点的元素8之间是元素6,我们可以把元素6和8合并成一个叶子节点:
在这里插入图片描述

4)删除元素在中间节点
在这里插入图片描述

如上图所示,删除的是中间节点的元素12,我们可以选择该元素的前驱或后继元素来顶替它的位置。在本例中,选择后继元素13更合适:
在这里插入图片描述

4.B树的缺点

B树不方便进行范围查询。

数据库的查询,不止涉及单一结果查询(比如查找学号是110235的学生),也会涉及一个区间内结果的查询(比如查找数学成绩60~80分的所有学生)。
对于前者,B树很容易实现,对于后者,由于区间内结果分布在各个层次的节
点当中,B树实现起来会非常烦琐,需要进行中序遍历,在父节点和子节点之间不断切换,给磁盘I/O带来很多负担。

二、B+树

B+树是B树的升级,它的结构设计为范围查询提供了便利。

B+树的特征

一个m阶的B+树具有如下几个特征:

  1. 有k个子树的中间节点包含k个元素(B树中是k-1个元素),每个元素不保存数据,所有数据都保存在叶子节点。
  2. 所有的叶子节点包含了全部元素,依照元素的大小升序排列,叶子节点之间用双向指针相连接。
  3. 所有中间节点的元素都同时存在于子节点,在子节点元素中是最大(或最小)元素。

在这里插入图片描述
如上图是一颗B+树,每一个父节点的元素都出现在子节点中,是子节点的最大(或最小)元素。父节点的所有元素都出现在子节点,因此叶子节点包含了整棵树的全量信息。并且每一个叶子节点都带有指向相邻叶子节点的指针,形成了一个双向有序链表。

B+树的设计,让我们可以很方便地进行范围查询。

要查找区间范围内的元素时,首先自顶向下,查找区间的最小值所在的叶子节点,再通过链表指针,遍历到相邻叶子节点,直到在叶子节点中找到区间最大值,这样就成功找出了区间内的所有元素。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[HackMyVM]靶场 Zon

kali:192.168.56.104 主机发现 arp-scan -l # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:d2:e0:49, IPv4: 192.168.56.104 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.56.1 0a:00:27:00:00:05 (Un…

Python和R的区别是什么,Python与R的应用场景是什么?

如果你这么问&#xff0c;那么你可能正站在数据科学的起点。对于志在成为数据专业人员的你来说&#xff0c;学习编程是无疑的。我想行你早就听过Python 与R的比较之声&#xff0c;并在选择中感到困惑。在此&#xff0c;我想说&#xff0c;也算是一种安慰吧&#xff1a;对于语言…

利用textarea和white-space实现最简单的文章编辑器 支持缩进和换行

当你遇到一个非常基础的文章发布和展示的需求&#xff0c;只需要保留换行和空格缩进&#xff0c;你是否会犹豫要使用富文本编辑器&#xff1f;实际上这个用原生的标签两步就能搞定&#xff01; 1.直接用textarea当编辑器 textarea本身就可以保存空格和换行符&#xff0c;示例如…

主存中存储单元地址的分配

主存中存储单元地址的分配 为什么写这篇文章? 因为我看书中这部分时&#xff0c;看到下面的计算一下子没反应过来&#xff1a; 知识回顾&#xff08;第1章&#xff09; 计算机系统中&#xff0c;字节是最小的可寻址的存储单位&#xff0c;通常由8个比特&#xff08;bit&…

IDEA直接打包Docker镜像

以下为使用IDEA打包Docker镜像并推送到远程仓库&#xff08;使用Windows打包Docker镜像并推送到远程仓库&#xff09;教程 1 安装Docker Desktop 下载地址&#xff1a;https://www.docker.com/products/docker-desktop/ 安装成功后&#xff0c;可在cmd查看版本号 2 启动Do…

天眼销批量查询功能上线

天眼销是一款提供企业线索的产品&#xff0c;致力于帮助客户获取最新的企业联系方式、工商信息等关键数据。 数据库收录全国 3.3亿及以上企业(含个体)线索&#xff0c;涵盖企业名称、企业状态、注册时间、注册资本、经营范围、法人信息、联系方式等维度&#xff0c;为用户提供…

安卓上最好用的Linux终端仿真软件:Termux 从入门到精通深度剖析

安卓上最好用的Linux终端仿真软件&#xff1a;Termux 从入门到精通深度剖析 前言引入安装Termux初识Termux界面介绍 基本使用快速编辑多会话更多菜单 高级操作termux.properties配置文件&#xff08;修改后需要重启termux生效&#xff09;通用设置General全屏模式Fullscreen mo…

机器人在果园内行巡检仿真

文章目录 创建工作空间仿真果园场景搭建小车模型搭建将机器人放在仿真世界中创建工作空间 mkdir -p ~/catkin_ws/src cd ~/catkin_ws仿真果园场景搭建 cd ~/catkin_ws/src git clone https://gitcode.com/clearpathrobotics/cpr_gazebo.git小车模型搭建 DiffBot是一种具有两个…

使用RabbitMQ,关键点总结

文章目录 1.MQ的基本概念2.常见的MQ产品3.MQ 的优势和劣势3.1 优势3.2 劣势 4.RabbitMQ简介4.1RabbitMQ 中的相关概念 1.MQ的基本概念 MQ全称 Message Queue&#xff08;消息队列&#xff09;&#xff0c;是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信。…

万界星空科技WMS仓储管理包含哪些具体内容?

wms仓库管理是通过入库业务、出库业务、仓库调拨、库存调拨和虚仓管理等功能&#xff0c;综合批次管理、物料对应、库存盘点、质检管理、虚仓管理和即时库存管理等功能综合运用的管理系统&#xff0c;有效控制并跟踪仓库业务的物流和成本管理全过程&#xff0c;实现完善的企业仓…

C语言 02 安装

C 语言的编译器有很多&#xff0c;其中最常用的是 GCC&#xff0c;这里以安装 GCC 为例。 Windows 这里以 Windows 11 为例 官方下载地址&#xff1a;https://www.mingw-w64.org/ 选择 Downloads 选择 Windows 的 GCC 环境 MingW-W64-builds 选择 GitHub 根据操作系统位…

堆排序(向下调整法,向上调整法详解)

目录 一、 二叉树的顺序结构 二、 堆的概念及结构 三、数组存储、顺序存储的规律 此处可能会有疑问&#xff0c;左右孩子的父节点计算为什么可以归纳为一个结论了&#xff1f; 四、大小堆解释 五、大小堆的实现&#xff08;向上和向下调整法&#xff09; 5.11向上调整法…

分布式事务的解决方案--Seata架构

一、Seata的XA模式 二、AT模式原理 三、TCC模式原理 四、MQ分布式事务 异步&#xff0c;非实时&#xff0c;实现最终的一致性。 四、分布式事务的解决方案

uniapp+uview 学习笔记(二)—— H5开发

文章目录 前言一、开发步骤1.创建项目2.安装组件库并导入使用3.封装请求4.国际化5.打包 总结 前言 本文主要介绍使用uniapp框架和uview组件库进行H5开发&#xff0c;需要用到的开发工具为HBuilder X。 一、开发步骤 1.创建项目 打开HBuilder X&#xff0c;在顶部栏目选择 新…

python知识点总结(四)

这里写目录标题 1、Django 中的缓存是怎么用的&#xff1f;2、现有2元、3元、5元共三种面额的货币&#xff0c;如果需要找零99元&#xff0c;一共有多少种找零的方式?3、代码执行结果4、下面的代码执行结果为&#xff1a;5、说一下Python中变量的作用域。6、闭包7、python2与p…

使用华为云HECS服务器+nodejs开启web服务

简介: 在华为云HECS服务器上使用nodejs开启一个web服务。 1.开通华为云服务器 这里我已经开通过了。 2.远程登录 2.1 使用华为官方的网页工具登录 输入密码登录。这里的密码应该在创建服务器时设置过的&#xff0c;由于已经创建过了&#xff0c;所以无法演示。 成功登…

视频技术2:把rtsp转为各种格式,包括webrtc

前题是启动ABLMediaServer&#xff0c;把ini里的hls_enable1 1、添加rtsp到视频服务器 http://127.0.0.1:7088/index/api/addStreamProxy?secret035c73f7-bb6b-4889-a715-d9eb2d1925cc&vhost_defaultVhost_&appMedia&streamCamera_00001&enable_hls1&ur…

SQLiteC/C++接口详细介绍之sqlite3类(十八)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十七&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;一&#xff09; ​ 56.sqlite3_update_hook 函数功能&am…

统计-R(相关系数)与R^2(决定系数)

1.相关系数&#xff08;R&#xff09; 定义&#xff1a;考察两个事物&#xff08;在数据里我们称之为变量&#xff09;之间的相关程度。 假设有两个变量X&#xff0c;Y&#xff0c;那么两个变量间的皮尔逊相关系数可通过以下公式计算&#xff1a; 公式一&#xff1a; 其中…

OkHttp

文章目录 OkHttp概要1.简介2.特点3.基本组成5.工作流程 拦截器1.简介2.内置拦截器3.自定义拦截器 连接池1.简介2.常用参数配置选项 Dispatcher和线程池1.简介2.重要方法3.DispatCher中的双端队列4.总结 OkHttp 概要 1.简介 OkHttp是一个开源的HTTP客户端&#xff0c;用于在J…