用Java实现B树的建立查找和删除

时间: 2024-02-05 22:12:45 浏览: 24
B树是一种广泛应用于数据库和文件系统中的数据结构,它的主要特点是能够高效地支持插入、查找和删除操作。下面是使用Java实现B树的简单示例代码。 B树节点类: ``` public class BTreeNode { private int t; // B树的度 private int keyNum; // 节点中关键字数量 private int[] keys; // 关键字数组 private boolean isLeaf; // 是否为叶子节点 private BTreeNode[] children; // 子节点数组 public BTreeNode(int t, boolean isLeaf) { this.t = t; this.isLeaf = isLeaf; this.keys = new int[2 * t - 1]; this.children = new BTreeNode[2 * t]; this.keyNum = 0; } public int getKeyNum() { return keyNum; } public int getKey(int index) { return keys[index]; } public void setKey(int index, int key) { keys[index] = key; } public boolean isLeaf() { return isLeaf; } public BTreeNode getChild(int index) { return children[index]; } public void setChild(int index, BTreeNode child) { children[index] = child; } public void setLeaf(boolean isLeaf) { this.isLeaf = isLeaf; } public void setKeyNum(int keyNum) { this.keyNum = keyNum; } } ``` B树类: ``` public class BTree { private BTreeNode root; // B树的根节点 private int t; // B树的度 public BTree(int t) { this.root = null; this.t = t; } // 查找操作 public BTreeNode search(int key) { return search(root, key); } private BTreeNode search(BTreeNode node, int key) { if (node == null) { return null; } int i = 0; while (i < node.getKeyNum() && key > node.getKey(i)) { i++; } if (i < node.getKeyNum() && key == node.getKey(i)) { return node; } if (node.isLeaf()) { return null; } else { return search(node.getChild(i), key); } } // 插入操作 public void insert(int key) { if (root == null) { root = new BTreeNode(t, true); root.setKey(0, key); root.setKeyNum(1); } else { if (root.getKeyNum() == 2 * t - 1) { BTreeNode newRoot = new BTreeNode(t, false); newRoot.setChild(0, root); root = newRoot; splitChild(root, 0); } insertNonFull(root, key); } } private void insertNonFull(BTreeNode node, int key) { int i = node.getKeyNum() - 1; if (node.isLeaf()) { while (i >= 0 && key < node.getKey(i)) { node.setKey(i + 1, node.getKey(i)); i--; } node.setKey(i + 1, key); node.setKeyNum(node.getKeyNum() + 1); } else { while (i >= 0 && key < node.getKey(i)) { i--; } i++; if (node.getChild(i).getKeyNum() == 2 * t - 1) { splitChild(node, i); if (key > node.getKey(i)) { i++; } } insertNonFull(node.getChild(i), key); } } private void splitChild(BTreeNode node, int i) { BTreeNode y = node.getChild(i); BTreeNode z = new BTreeNode(t, y.isLeaf()); z.setKeyNum(t - 1); for (int j = 0; j < t - 1; j++) { z.setKey(j, y.getKey(j + t)); } if (!y.isLeaf()) { for (int j = 0; j < t; j++) { z.setChild(j, y.getChild(j + t)); } } y.setKeyNum(t - 1); for (int j = node.getKeyNum(); j >= i + 1; j--) { node.setChild(j + 1, node.getChild(j)); } node.setChild(i + 1, z); for (int j = node.getKeyNum() - 1; j >= i; j--) { node.setKey(j + 1, node.getKey(j)); } node.setKey(i, y.getKey(t - 1)); node.setKeyNum(node.getKeyNum() + 1); } // 删除操作 public void delete(int key) { if (root == null) { return; } delete(root, key); if (root.getKeyNum() == 0) { root = root.getChild(0); } } private void delete(BTreeNode node, int key) { int i = 0; while (i < node.getKeyNum() && key > node.getKey(i)) { i++; } if (i < node.getKeyNum() && key == node.getKey(i)) { if (node.isLeaf()) { for (int j = i + 1; j < node.getKeyNum(); j++) { node.setKey(j - 1, node.getKey(j)); } node.setKeyNum(node.getKeyNum() - 1); } else { BTreeNode leftChild = node.getChild(i); BTreeNode rightChild = node.getChild(i + 1); if (leftChild.getKeyNum() >= t) { int pred = getPredecessor(node, i); node.setKey(i, pred); delete(leftChild, pred); } else if (rightChild.getKeyNum() >= t) { int succ = getSuccessor(node, i); node.setKey(i, succ); delete(rightChild, succ); } else { merge(node, i); delete(leftChild, key); } } } else { if (node.isLeaf()) { return; } boolean flag = (i == node.getKeyNum()); BTreeNode child = node.getChild(i); if (child.getKeyNum() < t) { fill(node, i); } if (flag && i > node.getKeyNum()) { delete(node.getChild(i - 1), key); } else { delete(node.getChild(i), key); } } } private int getPredecessor(BTreeNode node, int index) { BTreeNode cur = node.getChild(index); while (!cur.isLeaf()) { cur = cur.getChild(cur.getKeyNum()); } return cur.getKey(cur.getKeyNum() - 1); } private int getSuccessor(BTreeNode node, int index) { BTreeNode cur = node.getChild(index + 1); while (!cur.isLeaf()) { cur = cur.getChild(0); } return cur.getKey(0); } private void fill(BTreeNode node, int index) { if (index != 0 && node.getChild(index - 1).getKeyNum() >= t) { borrowFromPrev(node, index); } else if (index != node.getKeyNum() && node.getChild(index + 1).getKeyNum() >= t) { borrowFromNext(node, index); } else { if (index != node.getKeyNum()) { merge(node, index); } else { merge(node, index - 1); } } } private void borrowFromPrev(BTreeNode node, int index) { BTreeNode child = node.getChild(index); BTreeNode sibling = node.getChild(index - 1); for (int i = child.getKeyNum() - 1; i >= 0; i--) { child.setKey(i + 1, child.getKey(i)); } if (!child.isLeaf()) { for (int i = child.getKeyNum(); i >= 0; i--) { child.setChild(i + 1, child.getChild(i)); } } child.setKey(0, node.getKey(index - 1)); if (!sibling.isLeaf()) { child.setChild(0, sibling.getChild(sibling.getKeyNum())); } node.setKey(index - 1, sibling.getKey(sibling.getKeyNum() - 1)); child.setKeyNum(child.getKeyNum() + 1); sibling.setKeyNum(sibling.getKeyNum() - 1); } private void borrowFromNext(BTreeNode node, int index) { BTreeNode child = node.getChild(index); BTreeNode sibling = node.getChild(index + 1); child.setKey(child.getKeyNum(), node.getKey(index)); if (!child.isLeaf()) { child.setChild(child.getKeyNum() + 1, sibling.getChild(0)); } node.setKey(index, sibling.getKey(0)); for (int i = 1; i < sibling.getKeyNum(); i++) { sibling.setKey(i - 1, sibling.getKey(i)); } if (!sibling.isLeaf()) { for (int i = 1; i <= sibling.getKeyNum(); i++) { sibling.setChild(i - 1, sibling.getChild(i)); } } child.setKeyNum(child.getKeyNum() + 1); sibling.setKeyNum(sibling.getKeyNum() - 1); } private void merge(BTreeNode node, int index) { BTreeNode child = node.getChild(index); BTreeNode sibling = node.getChild(index + 1); child.setKey(t - 1, node.getKey(index)); for (int i = 0; i < sibling.getKeyNum(); i++) { child.setKey(i + t, sibling.getKey(i)); } if (!child.isLeaf()) { for (int i = 0; i <= sibling.getKeyNum(); i++) { child.setChild(i + t, sibling.getChild(i)); } } for (int i = index + 1; i < node.getKeyNum(); i++) { node.setKey(i - 1, node.getKey(i)); } for (int i = index + 2; i <= node.getKeyNum(); i++) { node.setChild(i - 1, node.getChild(i)); } child.setKeyNum(2 * t - 1); node.setKeyNum(node.getKeyNum() - 1); } } ``` 这是一个简单的B树实现,仅供参考。在实际应用中,可能需要根据具体情况进行优化和改进。

相关推荐

最新推荐

recommend-type

完整B树算法Java实现代码

主要为大家详细介绍了完整的B树算法Java实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

java实现遍历树形菜单两种实现代码分享

主要介绍了java实现遍历树形菜单两种实现代码分享,两种实现:OpenSessionView实现、TreeAction实现。具有一定参考价值,需要的朋友可以了解下。
recommend-type

java利用递归调用实现树形菜单的样式

主要给大家介绍了关于java利用递归调用实现树形菜单样式的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
recommend-type

Java实现的决策树算法完整实例

主要介绍了Java实现的决策树算法,简单描述了决策树的概念、原理,并结合完整实例形式分析了java实现决策树算法的相关操作技巧,代码中备有较为详尽的注释便于理解,需要的朋友可以参考下
recommend-type

java实现创建临时文件然后在程序退出时自动删除文件

主要介绍了java实现创建临时文件然后在程序退出时自动删除文件,从个人项目中提取出来的,小伙伴们可以直接拿走使用。
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

用 Python 画一个可以动的爱心

好的,我可以帮助您使用Python来绘制一个动态的爱心。您可以使用turtle库来实现。以下是实现代码: ```python import turtle import math # 设置画布和画笔 canvas = turtle.Screen() canvas.bgcolor("black") pencil = turtle.Turtle() pencil.speed(0) pencil.color("red", "pink") pencil.pensize(3) # 定义爱心函数 def draw_love(heart_size, x_offset=0, y_offset=0):
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。