Java数据结构和算法(B树)

前言

B树又叫平衡的多路搜索树;平衡的意思是又满足平衡二叉树的一些性质,左树大于右树;
多路意思是,可以多个结点,不再是像二叉树只有两个结点;

实现原理

B树是一种自平衡的搜索树,通常用于实现数据库和文件系统中的索引。它通过保持节点的平衡结构来保证插入、删除和查找操作在对数时间内完成。B树的具体实现原理包括以下几个方面:

1. 结构

  • 节点:每个节点包含多个键和指向子节点的指针。一个节点最多可以包含 m-1 个键和 m 个指针,其中 m 是B树的阶。
  • 根节点:根节点是树的顶部节点,特殊情况下,根节点可以是一个叶子节点(当树为空或只有一个节点时)。
  • 内部节点:非叶子节点,包含指向子节点的指针。
  • 叶子节点:没有子节点的节点,包含数据记录或指向数据记录的指针。

2. 性质

  1. 键的顺序:每个节点中的键按升序排列。
  2. 节点子树:对于一个节点 N 和其中的键 K_i,所有在 K_i 左边的子树中的键都小于 K_i,所有在 K_i 右边的子树中的键都大于 K_i
  3. 平衡性:所有叶子节点位于同一层次,这保证了树的平衡。
  4. 节点容量:除了根节点外,每个节点至少包含 ⌈m/2⌉ - 1 个键,最多包含 m-1 个键。

3. 操作

查找

从根节点开始,逐层向下查找:

  1. 在当前节点中找到第一个大于或等于目标键的位置 i
  2. 如果 K_i 正好等于目标键,则查找成功。
  3. 如果目标键小于 K_i 或在所有键后,递归地在对应的子树中继续查找。
插入
  1. 找到插入位置:从根节点开始,找到插入键的位置。
  2. 分裂节点:如果插入键导致某个节点的键超过 m-1,则将该节点分裂为两个节点,并将中间键提升到父节点。
  3. 递归分裂:如果提升的中间键导致父节点也超过 m-1 键,则继续向上分裂,直到根节点。如果根节点也需要分裂,则树的高度增加。
删除
  1. 找到删除位置:从根节点开始,找到要删除的键。
  2. 叶子节点删除:如果键在叶子节点,直接删除。
  3. 内部节点删除:如果键在内部节点,找到适当的替代键(前驱或后继),并递归删除替代键。
  4. 合并节点:如果删除键导致某个节点的键少于 ⌈m/2⌉ - 1,需要通过与兄弟节点合并或借用兄弟节点的键来维持B树性质。

具体代码实现

class AVLTreeNode {int key;int height;AVLTreeNode left;AVLTreeNode right;AVLTreeNode(int key) {this.key = key;this.height = 0;this.left = this.right = null;}
}public class AVLTree {private AVLTreeNode root;public AVLTree() {root = null;}// 获取以节点为根的树的高度private int height(AVLTreeNode node) {if (node == null) {return 0;}return node.height;}// 更新节点的高度private void updateHeight(AVLTreeNode node) {node.height = Math.max(height(node.left), height(node.right)) + 1;}// 左旋private AVLTreeNode rotateLeft(AVLTreeNode node) {AVLTreeNode rightNode = node.right;node.right = rightNode.left;rightNode.left = node;updateHeight(node);updateHeight(rightNode);return rightNode;}// 右旋private AVLTreeNode rotateRight(AVLTreeNode node) {AVLTreeNode leftNode = node.left;node.left = leftNode.right;leftNode.right = node;updateHeight(node);updateHeight(leftNode);return leftNode;}// 左右旋(先左后右)private AVLTreeNode rotateLR(AVLTreeNode node) {node.left = rotateLeft(node.left);return rotateRight(node);}// 右左旋(先右后左)private AVLTreeNode rotateRL(AVLTreeNode node) {node.right = rotateRight(node.right);return rotateLeft(node);}// 插入节点public void insert(int key) {root = insert(root, key);}// 递归插入并平衡private AVLTreeNode insert(AVLTreeNode node, int key) {if (node == null) {return new AVLTreeNode(key);}if (key < node.key) {node.left = insert(node.left, key);if (height(node.left) - height(node.right) == 2) {if (key < node.left.key) {node = rotateRight(node);} else {node = rotateLR(node);}}} else if (key > node.key) {node.right = insert(node.right, key);if (height(node.right) - height(node.left) == 2) {if (key > node.right.key) {node = rotateLeft(node);} else {node = rotateRL(node);}}}updateHeight(node);return node;}
}

QA:待定

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

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

相关文章

MySQL和MongoDB数据库的区别

MySQL和MongoDB数据库的区别 随着大数据和云计算技术的兴起&#xff0c;数据库的选择成为开发者和架构师必须面对的重要决策。MySQL和MongoDB作为关系型数据库和非关系型数据库的代表&#xff0c;在各自领域都有着广泛的应用。本文将从多方面详细比较MySQL和MongoDB&#xff0…

MATLAB:插值函数之interp与griddata

MATLAB 提供了多种插值函数来处理不同维度的数据。其中&#xff0c;interp1、interp2 和 griddata 是常用的插值函数&#xff0c;分别用于一维、二维和多维&#xff08;不规则&#xff09;数据的插值。 之前有对interp1进行过详细介绍&#xff0c;如需详细了解&#xff0c;请查…

会声会影调速怎么用 会声会影如何调整音频速度

会声会影是一款功能强大的视频编辑软件&#xff0c;可以帮助我们轻松的实现剪辑。 会声会影的操作简单易懂&#xff0c;界面简洁明快。适合家庭使用&#xff0c; 我们使用会声会影可以在家就能将视频剪辑成好莱坞大片。但是在使用的过程中&#xff0c;仍然会遇到一些操作上的问…

洛谷 P3803 【模板】多项式乘法(FFT)

【模板】多项式乘法&#xff08;FFT&#xff09; 题目背景 这是一道多项式乘法模板题。 注意&#xff1a;本题并不属于中国计算机学会划定的提高组知识点考察范围。 题目描述 给定一个 n n n 次多项式 F ( x ) F(x) F(x)&#xff0c;和一个 m m m 次多项式 G ( x ) G(…

C语言--指针数组和数组指针的区别

指针数组 就是一个数组&#xff0c;由指针构成的数组&#xff0c;每一个元素都是指针&#xff0c;每个指针可以指向不同的内存地址&#xff0c;这些地址可以是数组、变量。 int var1 10; int var2 20; int var3 30;int *ptrArray[3]; // 定义一个指针数组&#xff0c;包含…

2024年上半年软件系统架构师论文【回忆版】

文章目录 考试时间考试地点案例分析1、微服务架构的优点和缺点2、质量属性的6个元素3、分布式锁 Redis的缺点4、MongoDB 存储矢量图的优势 论文回忆版论文一、论单元测试的设计与应用论文二、论大数据模型的设计与应用论文三、论模型驱动的架构设计及应用论文四、论云原生运维的…

Mybatis-Plus-Join

1. 简介 官网 https://mybatisplusjoin.com/ 2. 基本用法 步骤&#xff1a; 添加依赖 <!--mybatis-plus-join--> <dependency><groupId>com.github.yulichang</groupId><artifactId>mybatis-plus-join-boot-starter</artifactId><ve…

探索LangGraph:如何创建一个既智能又可控的航空客服AI

这种设计既保持了用户控制权&#xff0c;又确保了对话流程的顺畅。但随着工具数量的增加&#xff0c;单一的图结构可能会变得过于复杂。我们将在下一节中解决这个问题。 第三部分的图将类似于下面的示意图&#xff1a; 状态定义 首先&#xff0c;定义图的状态。我们的状态和L…

homography原理和图像相似度计算

1. homography 讲homography原理 讲homography应用 2. 图像相似度计算 20230621-计算两幅图像的相似度 20221205-有史以来最全的图像相似度算法 20231112-图像相似度对比方法

C++:List的使用和模拟实现

✨✨✨学习的道路很枯燥&#xff0c;希望我们能并肩走下来! 文章目录 目录 文章目录 前言 一 list的介绍及使用 1.1 list的介绍 1.2 list的使用 1.2.1 list的构造 1.2.2 list iterator的使用 1.2.3 list capacity 1.2.4 list element access 1.2.5 list modifiers …

golang+redis的延时队列

网址 https://github.com/cfanbo/delay-queue-redis 代码结构很简单&#xff0c;简单代表着自由度很高&#xff0c;使用过程中出现问题也很好修改。 我很喜欢这样的代码&#xff0c;至少我看的懂&#xff0c;该有的都有。 //package main // //import ( // "context&q…

leetcode209_长度最小的子数组

要求某个连续的区间内的元素值总和>S . 思路&#xff1a;滑动窗口&#xff1a;本质上是一种双指针法。 &#xff08;1&#xff09;初始化left right 0&#xff1b; &#xff08;2&#xff09;left不动&#xff0c;right移动&#xff0c;扩大窗口&#xff0c;直至符合要…

selinux的安全策略可以影响ntp的方式

SELinux 是一个灵活而强大的模块化安全策略框架&#xff0c;它允许管理员定义和执行非常具体的访问控制策略。这些策略可以限制程序和进程对系统资源的访问&#xff0c;包括文件、网络端口、进程间通信等。 对于NTP&#xff0c;SELinux 策略可以影响以下几个方面&#xff1a; …

网络空间安全数学基础·整除与同余

主要内容&#xff1a; 整除的基本概念&#xff08;掌握&#xff09; 素数&#xff08;掌握&#xff09; 同余的概念&#xff08;掌握&#xff09; 1.1整除 定义&#xff1a;设a&#xff0c;b是任意两个整数&#xff0c;其中b≠0&#xff0c;如果存在一个整数q&#xff0c;使 …

12306技术内幕

公司内部做的一次技术分享 文章目录 12306的成就12306系统特点12306系统难点解决思路产品角度技术角度余票库存的表如何设计&#xff1f; 抢票软件推荐巨人的肩膀 对于未公开的技术部分&#xff0c;只能结合已公开的信息&#xff0c;去做大胆的猜想。 本文提到的一些解决方案&…

SpringBoot + Mybatis-Plus中乐观锁实现

悲观锁 悲观锁是一种悲观思想&#xff0c;它认为数据很可能会被别人所修改 所以总会对数据进行上锁&#xff0c;读操作和写操作都会上锁&#xff0c;性能较低&#xff0c;使用较少&#xff01; 乐观锁 乐观锁是一种乐观思想&#xff0c;它认为数据并不一定会被别人所修改 所以…

成为程序员后我都明白了什么?从入行到弃坑?

作为一个入行近10年的php程序员&#xff0c;真心感觉一切都才刚开始&#xff0c;对计算机&#xff0c;编程语言的理解也好&#xff0c;程序员中年危机也罢&#xff0c;之前都是听别人说的&#xff0c;真的自己到了这个水平&#xff0c;这个年龄才深刻体会到这其中的种种。 我一…

测试基础05:软件测试的分类

课程大纲 1、两种架构&#xff08;Architecture&#xff09; 1.1、B/S&#xff08;Browser/Server&#xff09; 浏览器服务器架构&#xff08;大体3步&#xff09;&#xff1a;用户通过浏览器向服务器发出请求&#xff0c;服务器处理请求&#xff0c;将结果通过网络返回到用户…

使用Webcam实现摄像头的开启和关闭,并保存和复制图片

实现思路 0&#xff0c;将webcam的jar文件传入项目中 1&#xff0c;显示摄像头的地方&#xff1a;创建一个画板&#xff0c;在画板上添加开启和关闭按钮 2&#xff0c;设置开启和关闭功能&#xff1a;创建一个类实现动作监听器&#xff0c;进而实现监听动作按钮 3&#xff…