B树及其Java实现详解

文章目录

  • B树及其Java实现详解
    • 一、引言
    • 二、B树的结构与性质
      • 1、节点结构
      • 2、性质
    • 三、B树的操作
      • 1、插入操作
        • 1.1、插入过程
      • 2、删除操作
        • 2.1、删除过程
      • 3、搜索操作
    • 四、B树的Java实现
      • 1、节点类实现
      • 2、B树类实现
    • 五、使用示例
    • 六、总结

B树及其Java实现详解

在这里插入图片描述

一、引言

B树是一种多路平衡查找树,广泛应用于数据库和文件系统的索引结构中。与传统的二叉搜索树相比,B树通过在每个节点存储多个键值对,减少了树的高度,从而降低了磁盘I/O操作的次数,提高了数据检索效率。B树的每个节点最多可以有m个子节点,其中m是B树的阶数。

二、B树的结构与性质

1、节点结构

B树的每个节点包含以下属性:

  • 键值列表:存储键值对的列表。
  • 子节点列表:存储子节点的列表。
  • 叶子节点标志:标识该节点是否为叶子节点。
  • 最小度数:节点的最小度数t,决定了节点中键值对的最小和最大数量。

2、性质

  • 平衡性:所有叶子节点到根节点的距离相同。
  • 键值范围:每个节点中的键值对按顺序排列,非叶子节点的键值用于分隔子树。
  • 子节点数量:非叶子节点的子节点数量等于键值对数量加1。

三、B树的操作

1、插入操作

1.1、插入过程
  • 寻找插入位置:从根节点开始,根据键值大小向下查找,直到找到合适的叶子节点。
  • 插入键值:将新键值插入到叶子节点的键值列表中。
  • 节点分裂:如果插入后叶子节点的键值对数量超过最大值,则需要分裂节点。分裂时,将中间键值提升到父节点,并将节点分成两个子节点。

2、删除操作

2.1、删除过程
  • 寻找删除位置:从根节点开始,查找要删除的键值所在的位置。
  • 删除键值:如果键值在叶子节点中,直接删除;如果在非叶子节点中,用其后继或前驱键值替换,并在相应的子树中删除替换的键值。
  • 节点合并:删除后,如果节点的键值对数量小于最小值,则需要合并节点。

3、搜索操作

  • 搜索过程:从根节点开始,根据键值大小向下查找,直到找到目标键值或到达叶子节点。在节点内使用二分查找法定位键值。

四、B树的Java实现

1、节点类实现

import java.util.ArrayList;
import java.util.List;class BTreeNode<T extends Comparable<T>> {int t;  // 最小度数List<T> keys;  // 存储键List<BTreeNode<T>> children;  // 存储子节点boolean leaf;  // 是否为叶子节点BTreeNode(int t, boolean leaf) {this.t = t;this.leaf = leaf;this.keys = new ArrayList<>();this.children = new ArrayList<>();}// 查找键int findKey(T k) {int idx = 0;while (idx < keys.size() && keys.get(idx).compareTo(k) < 0) {idx++;}return idx;}// 插入非满节点void insertNonFull(T k) {int i = keys.size() - 1;if (leaf) {keys.add(null);while (i >= 0 && keys.get(i).compareTo(k) > 0) {keys.set(i + 1, keys.get(i));i--;}keys.set(i + 1, k);} else {while (i >= 0 && keys.get(i).compareTo(k) > 0) {i--;}if (children.get(i + 1).keys.size() == 2 * t - 1) {splitChild(i + 1, children.get(i + 1));if (keys.get(i + 1).compareTo(k) < 0) {i++;}}children.get(i + 1).insertNonFull(k);}}// 分裂子节点void splitChild(int i, BTreeNode<T> y) {BTreeNode<T> z = new BTreeNode<>(y.t, y.leaf);for (int j = 0; j < t - 1; j++) {z.keys.add(y.keys.remove(t));}if (!y.leaf) {for (int j = 0; j < t; j++) {z.children.add(y.children.remove(t));}}children.add(i + 1, z);keys.add(i, y.keys.remove(t - 1));}
}

2、B树类实现

class BTree<T extends Comparable<T>> {int t;  // 最小度数BTreeNode<T> root;  // 根节点BTree(int t) {this.t = t;this.root = new BTreeNode<>(t, true);}// 插入键值void insert(T k) {if (root.keys.size() == 2 * t - 1) {BTreeNode<T> newRoot = new BTreeNode<>(t, false);newRoot.children.add(root);newRoot.splitChild(0, root);int i = 0;if (newRoot.keys.get(0).compareTo(k) < 0) {i++;}newRoot.children.get(i).insertNonFull(k);root = newRoot;} else {root.insertNonFull(k);}}// 删除键值void delete(T k) {// 删除操作的实现较为复杂,涉及到节点的合并和调整// 这里省略具体实现,可参考相关资料}// 搜索键值BTreeNode<T> search(T k) {return search(root, k);}private BTreeNode<T> search(BTreeNode<T> node, T k) {int i = 0;while (i < node.keys.size() && node.keys.get(i).compareTo(k) < 0) {i++;}if (i < node.keys.size() && node.keys.get(i).compareTo(k) == 0) {return node;}if (node.leaf) {return null;} else {return search(node.children.get(i), k);}}
}

五、使用示例

以下是一个简单的B树使用示例,演示了如何插入和搜索键值:

public class BTreeDemo {public static void main(String[] args) {BTree<Integer> bTree = new BTree<>(3);  // 创建一个最小度数为3的B树// 插入键值bTree.insert(10);bTree.insert(20);bTree.insert(30);bTree.insert(40);bTree.insert(50);bTree.insert(60);bTree.insert(70);// 搜索键值BTreeNode<Integer> node = bTree.search(40);if (node != null) {System.out.println("找到键值40");} else {System.out.println("未找到键值40");}}
}

六、总结

B树作为一种高效的平衡查找树,通过在每个节点存储多个键值对,减少了树的高度,降低了磁盘I/O操作的次数,提高了数据检索效率。在数据库和文件系统中,B树被广泛应用于索引结构。掌握B树的结构和操作对于理解和优化数据库索引具有重要意义。


版权声明:本博客内容为原创,转载请保留原文链接及作者信息。

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

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

相关文章

本地缓存:Guava Cache

这里写目录标题 一、范例二、应用场景三、加载1、CacheLoader2、Callable3、显式插入 四、过期策略1、基于容量的过期策略2、基于时间的过期策略3、基于引用的过期策略 五、显示清除六、移除监听器六、清理什么时候发生七、刷新八、支持更新锁定能力 一、范例 LoadingCache<…

【STM32】LED状态翻转函数

1.利用状态标志位控制LED状态翻转 在平常编写LED状态翻转函数时&#xff0c;通常利用状态标志位实现LED状态的翻转。如下所示&#xff1a; unsigned char led_turn_flag; //LED状态标志位&#xff0c;1-点亮&#xff0c;0-熄灭/***************************************函…

【高录用 | 快见刊 | 快检索】第十届社会科学与经济发展国际学术会议 (ICSSED 2025)

第十届社会科学与经济发展国际学术会议(ICSSED 2025)定于2025年2月28日-3月2日在中国上海隆重举行。会议主要围绕社会科学与经济发展等研究领域展开讨论。会议旨在为从事社会科学与经济发展研究的专家学者提供一个共享科研成果和前沿技术&#xff0c;了解学术发展趋势&#xff…

[ComfyUI]接入Google的Whisk,巨物融合玩法介绍

一、介紹​ 前段时间&#xff0c;谷歌推出了一个图像生成工具whisk&#xff0c;有一个很好玩的图片融合玩法&#xff0c;分别提供三张图片,就可以任何组合来生成图片。​ ​ 最近我发现有人开发了对应的ComfyUI插件&#xff0c;对whisk做了支持&#xff0c;就来体验了下&#…

模式识别与机器学习

文章目录 考试题型零、简介1.自学内容(1)机器学习(2)机器学习和统计学中常见的流程(3)导数 vs 梯度(4)KL散度(5)凸优化问题 2.基本概念3.典型的机器学习系统4.前沿研究方向举例 一、逻辑回归1.线性回归2.逻辑回归3.随堂练习 二、贝叶斯学习基础1.贝叶斯公式2.贝叶斯决策3.分类器…

nginx负载均衡-基于端口的负载均衡(一)

注意&#xff1a; (1) 做负载均衡技术至少需要三台服务器&#xff1a;一台独立的负载均衡器&#xff0c;两台web服务器做集群 一、nginx分别代理后端web1 和 web2的三台虚拟主机 1、web1&#xff08;nginx-10.0.0.7&#xff09;配置基于端口的虚拟主机 [rootOldboy extra]# …

图像模糊度(清晰度)检测 EsFFT 算法详细分析

图像模糊度检测算法 基于频域的算法 傅里叶变换法:先将图像进行傅里叶变换得到频谱图,频谱图中心为低频,向外扩展为高频。通过屏蔽频谱图中心区域实现高通滤波,保留图像边缘等高频信息,再求频谱图的均值即平均高频幅值,该值越小,图像越模糊。但传统FFT方法存在不足,如…

【ArcGIS微课1000例】0138:ArcGIS栅格数据每个像元值转为Excel文本进行统计分析、做图表

本文讲述在ArcGIS中,以globeland30数据为例,将栅格数据每个像元值转为Excel文本,便于在Excel中进行统计分析。 文章目录 一、加载globeland30数据二、栅格转点三、像元值提取至点四、Excel打开一、加载globeland30数据 打开配套实验数据包中的0138.rar中的tif格式栅格土地覆…

智能安全帽_4G/5G智能安全帽主板方案定制开发

智能安全帽是一种先进的安全防护设备&#xff0c;主要以视频和语音通话为功能&#xff0c;能够全面记录施工现场的作业情况&#xff0c;并支持管理人员与现场工作人员之间的双向语音通话。这一创新设计使得项目管理人员能够实时、有效地掌握施工过程中的安全和质量情况。 这款智…

uniApp通过xgplayer(西瓜播放器)接入视频实时监控

&#x1f680; 个人简介&#xff1a;某大型国企资深软件开发工程师&#xff0c;信息系统项目管理师、CSDN优质创作者、阿里云专家博主&#xff0c;华为云云享专家&#xff0c;分享前端后端相关技术与工作常见问题~ &#x1f49f; 作 者&#xff1a;码喽的自我修养&#x1f9…

为AI聊天工具添加一个知识系统 之26 资源存储库和资源管理器

本文要点 资源存储库 为了能完成本项目&#xff08;“为AI聊天工具增加一个知识系统”&#xff0c;其核心能力是“语言处理” &#xff0c;该能力的最大挑战 当仁不让的应该是自然语言处理&#xff09;的设计&#xff0c;我们考虑一个问题&#xff1a;在自然语言处理中&#…

基于RK3568/RK3588大车360度环视影像主动安全行车辅助系统解决方案,支持ADAS/DMS

产品设计初衷 HS-P2-2D是一款针对大车盲区开发的360度全景影像 安全行车辅助系统&#xff0c;通过车身四周安装的超广角像机&#xff0c;经算法合成全景鸟瞰图&#xff0c;通过鸟瞰图&#xff0c;司机非常清楚的看清楚车辆四周情况&#xff0c;大大降低盲区引发的交通事故。 产…

SQLite PRAGMA

SQLite的PRAGMA命令是一种特殊的命令&#xff0c;用于在SQLite环境中控制各种环境变量和状态标志。PRAGMA值可以被读取&#xff0c;也可以根据需求进行设置【0†source】。 PRAGMA命令的语法格式如下&#xff1a; 要查询当前的PRAGMA值&#xff0c;只需提供该PRAGMA的名字&am…

Oracle Dataguard(主库为双节点集群)配置详解(5):将主库复制到备库并启动同步

Oracle Dataguard&#xff08;主库为双节点集群&#xff09;配置详解&#xff08;5&#xff09;&#xff1a;将主库复制到备库并启动同步 目录 Oracle Dataguard&#xff08;主库为双节点集群&#xff09;配置详解&#xff08;5&#xff09;&#xff1a;将主库复制到备库并启动…

树的模拟实现

一.链式前向星 所谓链式前向星&#xff0c;就是用链表的方式实现树。其中的链表是用数组模拟实现的链表。 首先我们需要创建一个足够大的数组h&#xff0c;作为所有结点的哨兵位。创建两个足够大的数组e和ne&#xff0c;一个作为数据域&#xff0c;一个作为指针域。创建一个变…

【C++入门】详解(中)

目录 &#x1f495;1.函数的重载 &#x1f495;2.引用的定义 &#x1f495;3.引用的一些常见问题 &#x1f495;4.引用——权限的放大/缩小/平移 &#x1f495;5. 不存在的空引用 &#x1f495;6.引用作为函数参数的速度之快&#xff08;代码体现&#xff09; &#x1f4…

springboot整合mysql

1.首先在pom.xml中添加依赖&#xff1a; <!-- MySQL Driver --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><!-- Druid连接池 -->…

Windows C++开发环境:VSCode + cmake + ninja + msvc (cl.exe) + msys2/bash shell

这套环境的作用/优点 VSCode&#xff1a;代替Visual Studio, 启动迅速&#xff0c;内存占用小cmake: 与linux一致的构建系统ninja msvc: 用ninja作为cmake的generator, 配合msvc生成工具完成C工程的编译和链接 msvc作为编译工具&#xff0c;而不是msys2或mingw64的gcc&#x…

《Opencv》图像的旋转

一、使用numpy库实现 np.rot90(img,-1) 后面的参数为-1时事顺时针旋转&#xff0c;为1时是逆时针旋转。 import cv2 import numpy as np img cv2.imread(./images/kele.png) """方法一""" # 顺时针90度 rot_1 np.rot90(img,-1) # 逆时针90度…

CES 2025|全面拥抱端侧AI,美格智能在CES发布系列创新成果

要点&#xff1a; ▶ 在AI机器人领域&#xff0c;以高算力AI模组助力发布“通天晓”人形机器人和2款全新微小型AI机器人 ▶ 在AI硬件领域&#xff0c;发布消费级AI智能体产品——AIMO&#xff0c;引领个人专属的大模型时代 ▶ 在5G通信领域&#xff0c;发布全新5GWiFi-7 CPE…