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

b树(一篇文章带你 理解 )

目录

一、引言

二、B树的基本定义

三、B树的性质与操作

1 查找操作

2 插入操作

3 删除操作

四、B树的应用场景

1 数据库索引

2 文件系统

3 网络路由表

五、哪些数据库系统不使用B树进行索引

1 列式数据库

2 图形数据库

3 内存数据库

4 NoSQL数据库

5 分布式数据库

六、总结


一、引言

在计算机科学中,B树是一种自平衡的树,它能够保持数据有序,其插入与删除操作都能在对数时间内完成。

B树在数据库和文件系统的实现中尤为关键,因为它们能高效地保持数据有序,同时允许对数级别的插入、删除和查找操作。

B树相对于二叉搜索树的优势在于,它可以有效地利用存储空间,特别是在磁盘或类似的直接存取辅助设备中。

二、B树的基本定义

B树是一种平衡的多路搜索树,它满足以下条件:

  1. 所有叶子节点位于同一层。
  2. 每个非叶子节点包含n个关键字(k1, k2, ..., kn),其中n满足ceil(m/2) <= n <= m-1。对于每个关键字ki,ki < ki+1。
  3. 非叶子节点的子树指针p1, p2, ..., pn。其中所有关键字ki,i的子树指针pi指向的子树中所有关键字的值均大于ki且小于ki+1。
  4. 非叶子节点的子树个数=关键字个数+1。
  5. 所有关键字都出现在叶子节点的链表中(稠密索引),且链表中的节点是依次有序的。

其中,m是B树的阶数,它决定了树的最大和最小度数。一个m阶的B树,一个节点最多有m个子节点。

三、B树的性质与操作

B树作为一种自平衡树,其关键性质在于保持树的平衡,以保证查找、插入和删除操作的高效性。

1 查找操作

从根节点开始,根据键值比较进行路径选择,直到找到目标节点或到达叶子节点。B树的查找效率与树的高度相关,由于B树能够降低树的高度,因此查找效率较高。

  • 从根节点开始搜索,找到合适的叶子节点进行插入。
  • 如果插入后叶子节点关键字数不超过最大度数,则插入完成。
  • 否则,需要分裂该叶子节点,并将中间关键字提升到父节点。
  • 如果父节点也满了,则需要继续分裂并向上提升关键字,直到根节点或某个非满节点为止。
  • 如果根节点也分裂了,则需要创建一个新的根节点,并将两个子树的根节点作为新根节点的子节点。

2 插入操作

当插入一个新元素时,首先找到合适的位置,如果节点未满,则直接插入;如果节点已满,则需要进行分裂操作,将节点中的部分元素移动到新的节点中,并更新父节点。

分裂操作可能导致父节点也满,此时需要递归地进行分裂和更新操作,直到根节点或某个非满节点为止。

  • 从根节点开始搜索,找到包含要删除关键字的叶子节点。
  • 如果该叶子节点的关键字数大于最小度数,则直接删除该关键字。
  • 否则,需要从兄弟节点“借”一个关键字过来,或者与兄弟节点及父节点合并。
  • 删除操作可能触发一系列的合并和调整操作,直到满足B树的性质为止

以下是B树插入操作的Python伪代码:

def insert(node, key):if node is None:return create_new_node(key)i = node.find_position(key)if key == node.keys[i]:return node  # Key already exists, no insertionif node.is_leaf():node.insert_non_full(i, key)if node.is_full():return split_node(node)else:return nodeelse:child = node.children[i]child = insert(child, key)node.update_keys(i, child)if child is not None:return split_node(node) if node.is_full() else nodedef split_node(node):t = node.degree  # Assume degree is set for the treemid = t - 1new_node = create_new_node()new_node.keys = node.keys[mid:]new_node.children = node.children[mid+1:]node.keys = node.keys[:mid]node.children = node.children[:mid+1]new_node.children[-1] = None if node.is_leaf() else split_node(node.children[mid+1])node.parent = create_new_node() if node.parent is None else node.parentnode.parent.keys.append(node.keys[mid])node.parent.children.append(new_node)return node.parent

3 删除操作

删除操作相对复杂,因为需要保持B树的平衡性。当删除一个元素时,首先需要找到该元素所在的节点。

如果删除后节点不满,且兄弟节点有富余元素,则可以从兄弟节点借元素;如果兄弟节点也无富余元素,则需要进行合并操作,将当前节点与兄弟节点合并为一个新的节点,并更新父节点。合并操作可能导致父节点也不满,此时需要递归地进行合并和更新操作。

  • 从根节点开始,根据关键字比较结果选择子节点进行搜索。
  • 一直搜索到叶子节点,如果叶子节点包含要搜索的关键字,则搜索成功;否则搜索失败。

四、B树的应用场景

B树在计算机科学中有广泛的应用,特别是在处理大量数据时需要高效查找的场景中。以下是一些典型的应用场景:

1 数据库索引

在关系型数据库中,B树常被用作索引结构,以加快数据的查找速度。通过将数据按照键值排序并存储在B树中,数据库系统可以快速地定位到目标数据的位置。

2 文件系统

在文件系统中,B树也被用于目录结构的组织和查找。通过将目录项按照名称排序并存储在B树中,文件系统可以高效地定位到目标文件或目录。

3 网络路由表

在网络路由中,B树可以用于存储和查找路由信息。通过将IP地址或域名作为键值存储在B树中,路由器可以快速地找到目标地址的下一跳信息。

五、哪些数据库系统不使用B树进行索引

虽然B树及其变种(如B+树、B*树)是许多数据库系统实现索引的首选数据结构,但并非所有数据库系统都使用B树进行索引。以下是一些不使用B树进行索引的数据库系统的例子:

1 列式数据库

列式数据库,如Google的BigTable或Apache的Cassandra,它们的数据存储和索引方式与传统的行式数据库有所不同。这些系统通常基于键值对或列族进行数据存储和检索,因此可能不会使用传统的B树索引。

2 图形数据库

图形数据库,如Neo4j,专注于表示和查询图形结构的数据。它们通常使用专门的图算法和索引结构来加速查询,而不是传统的B树索引。

3 内存数据库

一些内存数据库,如Redis或Memcached,它们的数据主要存储在RAM中,以提供极快的读写速度。这些系统通常使用哈希表或其他内存友好的数据结构来支持快速查找,而不是B树。

4 NoSQL数据库

许多NoSQL数据库,如MongoDB(在某些情况下)和Cassandra,不依赖于传统的B树索引。MongoDB支持多种索引类型,包括哈希索引和地理空间索引,这些索引类型可能不使用B树结构。

5 分布式数据库

分布式数据库系统,如Spanner或CockroachDB,需要处理跨多个物理节点的数据。这些系统通常使用更复杂的索引和分区策略,可能不完全依赖于B树。

需要注意的是,即使某些数据库系统不使用B树进行索引,它们仍然可能使用其他类型的数据结构或算法来实现高效的查询性能。

此外,随着数据库技术的不断发展,新的索引结构和算法也在不断涌现,因此不能一概而论所有数据库系统都不使用B树进行索引。

在选择数据库系统时,了解其索引机制以及它如何支持特定的查询模式和数据访问需求是非常重要的。不同的数据库系统适用于不同的应用场景和工作负载,因此需要根据实际情况进行选择。

六、总结

B树作为一种高效的数据结构,在处理大量数据时具有显著的优势。通过了解其基本概念、性质、操作以及应用场景,我们可以更好地理解和应用B树算法。随着计算机技术的不断发展,B树将在更多领域发挥重要作用。

相关文章:

b树(一篇文章带你 理解 )

目录 一、引言 二、B树的基本定义 三、B树的性质与操作 1 查找操作 2 插入操作 3 删除操作 四、B树的应用场景 1 数据库索引 2 文件系统 3 网络路由表 五、哪些数据库系统不使用B树进行索引 1 列式数据库 2 图形数据库 3 内存数据库 4 NoSQL数据库 5 分布式数据…...

OD_2024_C卷_200分_7、5G网络建设【JAVA】【最小生成树】

package odjava;import java.util.Scanner;public class 七_5G网络建设 {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt(); // 基站数量&#xff08;节点数&#xff09;int m sc.nextInt(); // 基站对数量&#xff08;边数&…...

面试题:分布式锁用了 Redis 的什么数据结构

在使用 Redis 实现分布式锁时&#xff0c;通常使用 Redis 的字符串&#xff08;String&#xff09;。Redis 的字符串是最基本的数据类型&#xff0c;一个键对应一个值&#xff0c;它能够存储任何形式的字符串&#xff0c;包括二进制数据。字符串类型的值最多可以是 512MB。 Re…...

【学习心得】websocket协议简介并与http协议对比

一、轮询和长轮询 在websocket协议出现之前&#xff0c;要想实现服务器和客户端的双向持久通信采取的是Ajax轮询。它的原理是每隔一段时间客户端就给服务器发送请求找服务器要数据。 让我们通过一个生活化的比喻来解释轮询和长轮询假设你正在与一位不怎么主动说话的老大爷&…...

基于Token的身份验证:安全与效率的结合

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

Electron程序如何在MacOS下获取相册访问权限

1.通过entitiment.plist&#xff0c;在electron-builder签名打包时&#xff0c;给app包打上签名。最后可以通过codesign命令进行验证。 TestPhotos.plist electron-builder配置文件中加上刚刚的plist文件。 通过codesign命令验证&#xff0c;若出现这个&#xff0c;则说明成…...

uniapp让输入框保持聚焦状态,不会失去焦点

使用场景&#xff1a;当输入框还有发送按钮的时候&#xff0c;点击发送希望软键盘不消失&#xff0c;还可以继续输入&#xff0c;或者避免因输入图片标签造成的屏闪问题 多次尝试后发现一个很实用的方法&#xff0c;适用input输入框和editor输入框 解决办法&#xff1a;把cli…...

面试中如何介绍mysql的B+树

B树是B树的变体&#xff0c;也是一颗多路搜索树。在MySQL中&#xff0c;B树是为磁盘或者其他直接辅助存储设备所设计的一种平衡的查找树结构。其具有以下特点&#xff1a; 每个节点最多有m个子女&#xff0c;m阶的B树深度最多为m。非根节点关键值个数范围是⌈m/2⌉-1<k<m…...

【Linux C | 网络编程】多播的概念、多播地址、UDP实现多播的C语言例子

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…...

AIGC实战——GPT(Generative Pre-trained Transformer)

AIGC实战——GPT 0. 前言1. GPT 简介2. 葡萄酒评论数据集3. 注意力机制3.1 查询、键和值3.2 多头注意力3.3 因果掩码 4. Transformer4.1 Transformer 块4.2 位置编码 5. 训练GPT6. GPT 分析6.1 生成文本6.2 注意力分数 小结系列链接 0. 前言 注意力机制能够用于构建先进的文本…...

微信小程序-入门

一.通过 Npm方式下载构建 1.下载和安装Npm&#xff1a;Npm https://docs.npmjs.com/downloading-and-installing-node-js-and-npm 或者 https://nodejs.org/en/download/ 未安装npm 提示 以下以安装node安装包为例 按任意键继续 安装完成后 2. 下载和安装小程序开…...

0102全排列和对换-行列式-线性代数

把n个不同的数排成一列&#xff0c;叫做这n个数的全排列&#xff08;排列&#xff09;。 一般情况&#xff0c; 1 , 2 , ⋯ , n 1,2,\cdots,n 1,2,⋯,n是n个数排列的标准次序。 当n个数的任一排列中两个数的先后次序与标准次序不同时&#xff0c;有说有一个逆序。 一个排列中所…...

面向对象的编程语言是什么意思?——跟老吕学Python编程

面向对象的编程语言是什么意思&#xff1f;——跟老吕学Python编程 面向对象是什么意思&#xff1f;面向对象的定义面向对象的早期发展面向对象的背景1.审视问题域的视角2.抽象级别3.封装体4.可重用性 面向对象的特征面向对象的开发方法面向对象程序设计基本思想实现 面向对象的…...

Spring Boot整合MyBatis Plus配置多数据源

Spring Boot 专栏&#xff1a;https://blog.csdn.net/dkbnull/category_9278145.html Spring Cloud 专栏&#xff1a;https://blog.csdn.net/dkbnull/category_9287932.html GitHub&#xff1a;https://github.com/dkbnull/SpringBootDemo Gitee&#xff1a;https://gitee.com/…...

Unix Network Programming Episode 88

‘inetd’ Daemon On a typical Unix system, there could be many servers in existence, just waiting for a client request to arrive. Examples are FTP, Telnet, Rlogin, TFTP, and so on. With systems before 4.3BSD, each of these services had a process associate…...

Java面试题之11MySQL

你对MySQL执行计划怎么看 执行计划就是SQL的执行查询的顺序&#xff0c;以及如何使用索引查询&#xff0c;返回的结果集的行数 在MySQL中&#xff0c;我们可以通过explain命令来查看执行计划。其语法如下&#xff1a; EXPLAIN SELECT * FROM table_name WHERE conditions;在…...

R语言:多值提取到点

ArcGIS中有相关工具实现多值提取到点的功能&#xff0c;在这里&#xff0c;我将使用R语言进行操作&#xff1a; library(dplyr) library(readxl) library(sf) library(raster)setwd("D:/Datasets") Bio <- stack(paste0("D:/Datasets/Data/worldclim2_1km/…...

八股文打卡day27——数据库(4)

面试题&#xff1a;讲一下事务的隔离级别&#xff1f; 我的回答&#xff1a; 因为事务之间的隔离性&#xff0c;造成了一些问题&#xff0c;比如说&#xff1a;脏读、不可重复读和幻读&#xff08;虚读&#xff09;。 1.什么叫脏读&#xff1f; 就是一个事务读取到了另一个事…...

Java桥接模式源码剖析及使用场景

目录 一、介绍二、项目管理系统中使用桥接模式三、权限管理中使用桥接模式四、Java JDBC中使用桥接模式 一、介绍 它的主要目的是将抽象化与实现化分离&#xff0c;使得二者可以独立变化&#xff0c;就像一个桥&#xff0c;将两个变化维度连接起来。各个维度都可以独立的变化。…...

【异常处理】verilator安装时出现异常 make: *** [Makefile:195: verilator_gantt.1] Error 13

在ubuntu中安装verilator工具时执行make出现该报错。 当我出现这个报错的时候我一脸懵逼&#xff0c;因为网上找不到相关解决办法。 后来想到我的verilator是从github上下载zip&#xff0c;然后解压后传到ubuntu上的&#xff0c;windows上解压我记得会把-替换成_&#xff0c;这…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...