Java多路查找树(含面试大厂题和源码)

news/2024/4/30 7:21:22/文章来源:https://blog.csdn.net/2302_80314137/article/details/137505732

多路查找树(Multiway Search Tree),也称为B树或B+树,是一种自平衡的树形数据结构,用于存储大量数据,通常用于数据库和文件系统中。它允许在查找、插入和删除操作中保持数据的有序性,同时优化了磁盘I/O性能。

多路查找树的特点:

  1. 节点多个子节点:与二叉查找树不同,多路查找树的每个节点可以有多个子节点(超过两个)。
  2. 有序节点值:节点内部的值是有序的,通常按照升序或降序排列。
  3. 平衡树:树保持平衡,即所有叶子节点在同一层,或者只差一层。
  4. 分裂与合并操作:在插入或删除节点时,如果节点的子节点数量超过了预设的最大值,会进行节点分裂或合并操作,以保持树的平衡。
  5. 分层索引:多路查找树可以构建分层索引,顶层的节点包含指向下一层节点的指针,这样可以快速定位到数据所在的区域。

多路查找树的应用:

  • 数据库索引:多路查找树是许多数据库系统底层实现索引结构的基础,如B树和B+树。
  • 文件系统:在文件系统中,多路查找树可以用于跟踪文件的位置,优化文件的读取和写入操作。
  • 内存管理:在操作系统中,多路查找树可以用于管理内存的分配和回收。

多路查找树的Java实现(简单示例):

由于多路查找树的实现相对复杂,以下是一个简化版的多路查找树的插入操作的Java代码示例:

class MultiwayNode {int key;MultiwayNode[] children;boolean isLeaf;public MultiwayNode(int key) {this.key = key;this.isLeaf = true;this.children = new MultiwayNode[2 * order - 1]; // 假设order为树的阶数}
}class MultiwaySearchTree {private MultiwayNode root;private int order; // 树的阶数public MultiwaySearchTree(int order) {this.order = order;}public void insert(int key) {root = insertRec(root, key);}private MultiwayNode insertRec(MultiwayNode node, int key) {if (node == null) {return new MultiwayNode(key);}int i = 0;for (; i < node.children.length - 1; i++) {if (key < node.children[i].key) {break;}}if (node.children[i] == null) {node.children[i] = new MultiwayNode(key);return node;} else if (i < node.children.length - 1 && !node.children[i].isLeaf) {node.children[i] = insertRec(node.children[i], key);return node;} else {// 需要分裂节点MultiwayNode newNode = splitNode(node, i);return fuseNodes(node, newNode);}}private MultiwayNode splitNode(MultiwayNode node, int index) {// 实现节点分裂逻辑// ...return new MultiwayNode(node.children[index].key);}private MultiwayNode fuseNodes(MultiwayNode node1, MultiwayNode node2) {// 实现节点合并逻辑// ...return new MultiwayNode(node1.key);}
}// 使用示例
public class Main {public static void main(String[] args) {MultiwaySearchTree tree = new MultiwaySearchTree(3); // 假设树的阶数为3tree.insert(5);tree.insert(3);tree.insert(7);tree.insert(1);tree.insert(9);// 树的结构现在应该是平衡的}
}

在实际应用中,多路查找树的实现会更加复杂,包括处理节点分裂和合并的详细逻辑,以及维护树的平衡性。在面试中,了解多路查找树的基本概念和操作是非常重要的,它展示了你对数据结构和算法的深入理解。希望这些知识点和示例代码能够帮助你更好地准备面试!

题目 1:实现一个B树的插入操作

描述
实现一个B树的插入操作,B树是一种自平衡的多路查找树,用于维护排序的数据。给定一个B树和一个新的键值,将该键值插入到B树中,并保持树的平衡。

示例

假设B树的阶数为3,给定一个空的B树和键值[1, 2, 3, 4, 5, 6, 7],依次插入这些键值。

Java 源码

class BTreeNode {int key;BTreeNode[] children;boolean isLeaf;public BTreeNode(int key) {this.key = key;this.isLeaf = true;}
}class BTree {private int order;private BTreeNode root;public BTree(int order) {this.order = order;}public void insert(int key) {if (root == null) {root = new BTreeNode(key);return;}root = insertNonFull(root, key);}private BTreeNode insertNonFull(BTreeNode node, int key) {if (node.isLeaf) {int i = 0;while (i < node.children.length - 1 && key > node.children[i].key) {i++;}if (i < node.children.length) {BTreeNode newNode = new BTreeNode(key);node.children[i] = newNode;return node;}// Split the node and return the new rootreturn splitChild(node, i);} else {int i = 0;while (i < node.children.length && key < node.children[i].key) {i++;}if (i < node.children.length - 1 && !node.children[i].isLeaf) {node.children[i] = insertNonFull(node.children[i], key);} else {// Split the child node and update the parentnode.children[i] = splitChild(node.children[i], i);}}return balance(node);}private BTreeNode splitChild(BTreeNode child, int index) {int newKeys = (child.key > order / 2) ? order / 2 + 1 : order / 2;BTreeNode newChild = new BTreeNode(child.key[newKeys]);System.arraycopy(child.key, index + 1, newChild.key, 0, newKeys);child.key = Arrays.copyOfRange(child.key, 0, index + 1);child.key[newKeys - 1] = child.key[newKeys];child.key = Arrays.copyOf(child.key, newKeys);newChild.isLeaf = child.isLeaf;child.children = Arrays.copyOfRange(child.children, 0, index);child.children[newKeys - 1] = newChild;child.children = Arrays.copyOf(child.children, newKeys);return child;}private BTreeNode balance(BTreeNode node) {// Implement balancing logic if needed// ...return node;}
}// 使用示例
public class Main {public static void main(String[] args) {BTree tree = new BTree(3); // 假设B树的阶数为3for (int i = 1; i <= 7; i++) {tree.insert(i);}// B树现在应该包含所有插入的键值,并且保持平衡}
}

题目 2:实现一个B+树的查找操作

描述
实现一个B+树的查找操作,B+树是一种特殊的多路平衡查找树,所有的数据都存储在叶子节点中。给定一个B+树和一个键值,查找该键值是否存在于B+树中。

示例

假设B+树的阶数为4,给定一个B+树和键值[10, 20, 30, 40, 50, 60, 70],查找键值30是否存在。

Java 源码

class BPlusLeafNode {int[] keys;BPlusLeafNode next;public BPlusLeafNode(int[] keys) {this.keys = keys;}
}class BPlusNode {BPlusNode[] children;int[] keys;boolean isLeaf;public BPlusNode(int[] keys) {this.keys = keys;this.isLeaf = keys.length == 1;}
}class BPlusTree {private BPlusNode root;private int order;public BPlusTree(int order) {this.order = order;root = new BPlusNode(new int[]{});}public boolean search(int key) {return search(root, key);}private boolean search(BPlusNode node, int key) {if (node.isLeaf) {int i = 0;while (i < node.keys.length && key > node.keys[i]) {i++;}if (i < node.keys.length && node.keys[i] == key) {return true;}return false;} else {int i = 0;while (i < node.keys.length && key < node.keys[i]) {i++;}if (i < node.keys.length) {return search(node.children[i], key);}return search(node.children[node.children.length - 1], key);}}
}// 使用示例
public class Main {public static void main(String[] args) {BPlusTree tree = new BPlusTree(4);// 假设树已经通过插入操作构建好了boolean found = tree.search(30);System.out.println("Key 30 found: " + found);}
}

题目 3:实现一个B+树的范围查询操作

描述
实现一个B+树的范围查询操作,查询给定范围内的所有键值。B+树的所有数据都存储在叶子节点中,叶子节点之间通过指针相互连接。

示例

假设B+树的阶数为4,给定一个B+树和键值[10, 20, 30, 40, 50, 60, 70],查询范围在[20, 50]之间的所有键值。

Java 源码

public class BPlusTreeRangeSearch {private BPlusLeafNode findFirstLeaf(BPlusNode node, int start) {while (!node.isLeaf) {node = node.children[findFirstKeyIndex(node, start)];}return (BPlusLeafNode) node;}private int findFirstKeyIndex(BPlusNode node, int start) {int i = 0;while (i < node.keys.length - 1 && start > node.keys[i]) {i++;}return i;}public List<Integer> rangeSearch(BPlusNode root, int start, int end) {List<Integer> results = new ArrayList<>();BPlusLeafNode leaf = findFirstLeaf(root, start);if (leaf.keys[0] >= start) {int i = 0;while (leaf != null && i < leaf.keys.length && leaf.keys[i] >= start) {while (leaf.keys[i] <= end) {results.add(leaf.keys[i]);i++;}if (leaf.next != null) {leaf = leaf.next;i = 0;} else {break;}}}return results;}
}// 使用示例
public class Main {public static void main(String[] args) {BPlusTree tree = new BPlusTree(4);// 假设树已经通过插入操作构建好了BPlusTreeRangeSearch search = new BPlusTreeRangeSearch();List<Integer> results = search.rangeSearch(tree.root, 20, 50);System.out.println("Range search results: " + results);}
}

这些题目和源码展示了多路查找树在数据结构和算法问题中的应用。在面试中,能够根据问题的特点选择合适的算法并实现其解决方案是非常重要的。希望这些示例能够帮助你更好地准备面试!

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

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

相关文章

java学习之线程池

java线程池优点&#xff1a; 降低线程创建和销毁的开销&#xff0c;提高系统性能。 提高线程的利用率和系统的吞吐量。 统一线程的管理和监控&#xff0c;避免线程泄漏和线程安全问题。 支持任务队列和拒绝策略等机制&#xff0c;提供灵活的任务调度和任务处理能力。 并不…

String类(1)

❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; hellohello~&#xff0c;大家好&#x1f495;&#x1f495;&#xff0c;这里是E绵绵呀✋✋ &#xff0c;如果觉得这篇文章还不错的话还请点赞❤️❤️收藏&#x1f49e; &#x1f49e; 关注&#x1f4a5;&a…

随行付优化外卡收单,助力支付便利化

解决老年人和境外游客在支付过程中遇到的问题和障碍&#xff0c;正逐渐成为整个支付行业的焦点关注词汇。 在有关提高支付服务便利度的意见发布后&#xff0c;有关收单行业的好消息不断涌现&#xff1a;中国银联于3月15日宣布投入30亿元用于升级基础设施&#xff0c;促进支付便…

五一假期来临,各地景区云旅游、慢直播方案设计与平台搭建

一、行业背景 经文化和旅游部数据中心测算&#xff0c;今年清明节假期3天全国国内旅游出游1.19亿人次&#xff0c;按可比口径较2019年同期增长11.5%&#xff1b;国内游客出游花费539.5亿元&#xff0c;较2019年同期增长12.7%。踏青赏花和户外徒步成为假期的热门出游主题。随着…

HarmonyOS 开发-一镜到底“页面转场”动画

介绍 本方案做的是页面点击卡片跳转到详情预览的转场动画效果 效果图预览 使用说明 点击首页卡片跳转到详情页&#xff0c;再点击进入路由页面按钮&#xff0c;进入新的路由页面 实现思路 首页使用了一种视觉上看起来像是组件的转场动画&#xff0c;这种转场动画通常是通过…

09 spring-boot-acurator 定时检测 redis 集群导致 “IOException: Too many open files“

前言 问题的现象主要是如下 项目刚启动的时候 十分正常, 然后 随着时间的推移, 比如说 项目跑了 四五天之后 项目 突然出现问题, 一部分服务能够正常访问, 一部分服务抛出异常 异常信息 就是 too many files 这里的主要的问题是 在异常之前, redis 集群没有密码, 然后 …

Git的简单使用

Git 一&#xff1a;什么是Git&#xff1a; Git是一个分布式版本控制系统&#xff0c;用于跟踪文件的变化并协作开发项目。它允许多个开发者在同一时间内对同一个项目进行编辑&#xff0c;并能够轻松地管理不同版本的文件。Git通过记录文件的变化并创建快照来跟踪项目的历史记…

C++ //练习 11.14 扩展你在11.2.1节练习(第378页)中编写的孩子姓到名的map,添加一个pair的vector,保存孩子的名和生日。

C Primer&#xff08;第5版&#xff09; 练习 11.14 练习 11.14 扩展你在11.2.1节练习&#xff08;第378页&#xff09;中编写的孩子姓到名的map&#xff0c;添加一个pair的vector&#xff0c;保存孩子的名和生日。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#x…

论文阅读《Semantic Prompt for Few-Shot Image Recognition》

论文地址&#xff1a;https://arxiv.org/pdf/2303.14123.pdf 论文代码&#xff1a;https://github.com/WentaoChen0813/SemanticPrompt 目录 1、存在的问题2、算法简介3、算法细节3.1、预训练阶段3.2、微调阶段3.3、空间交互机制3.4、通道交互机制 4、实验4.1、对比实验4.2、组…

PicGo + Gitee + VsCode - 搭建私人图床

文章目录 前言搭建图床VsCode 安装插件安装 PicGo准备 Gitee 图床测试 尾声 前言 本人是一个重度 vimer&#xff0c;并且喜欢客制化一些东西… Typora 固然好用&#xff0c;但不支持 vim…发现 vscode 中既可以使用 vim&#xff0c;也可以 md&#xff0c;用起来比较舒服.因此…

关于ansible的模块 ③

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 接《关于Ansible的模块①》和《关于Ansible的模块②》&#xff0c;继续学习ansible的user模块。 user模块可以增、删、改linux远…

免费的GPT-3.5 API服务aurora

什么是 aurora &#xff1f; aurora 是利用免登录 ChatGPT Web 提供的无限制免费 GPT-3.5-Turbo API 的服务&#xff0c;支持使用 3.5 的 access 调用。 【注意】&#xff1a;仅 IP 属地支持免登录使用 ChatGPT的才可以使用&#xff08;也可以自定义 Baseurl 来绕过限制&#x…

MSOLSpray:一款针对微软在线账号(AzureO365)的密码喷射与安全测试工具

关于MSOLSpray MSOLSpray是一款针对微软在线账号&#xff08;Azure/O365&#xff09;的密码喷射与安全测试工具&#xff0c;在该工具的帮助下&#xff0c;广大研究人员可以直接对目标账户执行安全检测。支持检测的内容包括目标账号凭证是否有效、账号是否启用了MFA、租户账号是…

Linux学习-网络UDP

网络 数据传输,数据共享 网络协议模型 OSI协议模型 应用层 实际发送的数据 表示层 发送的数据是否加密 会话层 是否建立会话连接 传输层 数据传输的方式&#xff08;数据报、流式&#…

企业计算机服务器中了locked勒索病毒怎么办,locked勒索病毒解密流程步骤

网络技术的不断发展为企业的生产运营提供了极大便利&#xff0c;也让企业的生产效率大大提高&#xff0c;但网络是一把双刃剑&#xff0c;给给企业的数据安全问题带来严重威胁。近期&#xff0c;云天数据恢复中心接到浙江某商贸公司的求助&#xff0c;企业计算机服务器遭到了lo…

网络驱动器设备:ISCSI服务器

文章目录 使用ISCSI服务部署网络存储ISCSI技术介绍创建RAID磁盘整列配置ISCSI服务端配置Windows端配置Linux客户端iSCSI服务器CHAP单向认证配置Linux端具体步骤Windows端具体步骤 使用ISCSI服务部署网络存储 主机名IPISCSI服务端192.168.200.10ISCSI客户端192.168.200.20Windo…

UE5、CesiumForUnreal实现加载建筑轮廓GeoJson数据生成白模功能

1.实现目标 在UE5.3中,通过加载本地建筑边界轮廓面GeoJson数据,获取底面轮廓和楼高数据,拉伸生成白模,并支持点选高亮。为防止阻塞Game线程,使用了异步任务进行优化,GIF动图如下所示: 其中建筑数量:128871,顶点索引数量:6695748,三角面数量:2231916,顶点数量:165…

Linux nsenter命令全面解析

Linux nsenter命令是一个强大的工具&#x1f6e0;️&#xff0c;用于进入到已存在的命名空间&#xff08;Namespace&#xff09;中执行命令。由于Linux的命名空间技术是构建容器技术的基础&#xff0c;nsenter因此成为了容器管理和调试中不可或缺的工具&#x1f433;。本文将从…

【开源语音项目OpenVoice](一)——实操演示

目录 一、前菜 1、Python选择 2、pip源切换 3、ffmpeg配置问题 4、VSCode添加Jupyter扩展 二、配置虚拟环境 1、下载源码 方法一 直接下载源码压缩包 方法二 使用git 1&#xff09;git加入鼠标右键 2&#xff09;git clone源码 2、VSCode出场 1&#xff09;创建pyth…

vue实现验证码验证登录

先看效果&#xff1a; 代码如下&#xff1a; <template><div class"container"><div style"width: 400px; padding: 30px; background-color: white; border-radius: 5px;"><div style"text-align: center; font-size: 20px; m…