`
robertliudeqiang
  • 浏览: 123300 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

B树算法的java实现

阅读更多
B树算法及其变种多用于文件,数据库索引,下面是参考“算法导论”的java实现,可以加入节点,没有提供删除结点功能,打印的信息还行,仅供学习。

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/*
 * Author: Robert Liu
 */
public class BTree<E extends Comparable<E>> {
	private BTNode root = null;
	private int t;
	private final int fullNum;

	public BTree(int t) {
		this.t = t;
		fullNum = 2 * t - 1;
	}

	private final BTNode NullBTNode = new BTNode();

	private class BTNode {
		private int number = 0;
		private List<E> values = new ArrayList<E>();
		private List<BTNode> children = new ArrayList<BTNode>();
		private boolean isLeaf = false;

		E getKey(int i) {
			return values.get(i);
		}

		BTNode getChildren(int i) {
			return children.get(i);
		}

		void AddKey(int i, E element) {
			values.add(i, element);
		}

		void removeKey(int i) {
			values.remove(i);
		}

		void AddChildren(int i, BTNode c) {
			children.add(i, c);
		}

		void removeChildren(int i) {
			children.remove(i);
		}

		boolean isFull() {
			if (number == fullNum)
				return true;
			return false;
		}

		int getSize() {
			return values.size();
		}

		boolean isNull() {
			return (this == NullBTNode);
		}

		@Override
		public String toString() {
			if (number == 0)
				return "NullNode";

			StringBuilder sb = new StringBuilder();
			sb.append("[N: " + number + "] [values: ");
			for (E e : values) {
				sb.append(e + ", ");
			}
			sb.append(" ] [ children: ");
			for (BTNode bNode : children) {
				if (bNode == NullBTNode)
					sb.append(bNode + ", ");
				else
					sb.append("NotNullNode" + ", ");
			}
			sb.append("] [childrenSize: " + children.size());
			sb.append("] [ isLeaf: " + isLeaf);
			sb.append("]");
			return sb.toString();
		}
	}

	// Generate the root node
	private void constructRoot(E elem) {
		root = new BTNode();
		root.number = 1;
		root.AddKey(0, elem);
		root.isLeaf = false;
	}

	private void addElemToNode(BTNode node, E element, int i) {
		node.AddKey(i, element);
		node.number++;
		node.AddChildren(i, NullBTNode);
	}

	public void insertElem(E elem) {
		if (root == null) {
			// The first node
			constructRoot(elem);
			root.isLeaf = true;
			root.AddChildren(0, NullBTNode);
			root.AddChildren(1, NullBTNode);
			return;
		}

		BTNode curNode = root;

		if (root.isFull()) {
			// Extend the root
			constructRoot(curNode.getKey(t - 1));

			// Get new node
			BTNode newNode = getExtendedNode(curNode);

			// Process old full node
			processFullNode(curNode);

			// Process root
			root.AddChildren(0, curNode);
			root.AddChildren(1, newNode);
			return;
		}

		int i = 0;
		BTNode childNode = null;
		// Find the node to insert
		while (true) {
			while ((i < curNode.getSize())
					&& (elem.compareTo(curNode.getKey(i)) > 0)) {
				i++;
			}

			childNode = curNode.getChildren(i);
			if (childNode.isFull()) {
				// Split the node

				// Add the element to parent
				curNode.number++;
				curNode.AddKey(i, childNode.getKey(t - 1));

				// New node for extension
				BTNode newNode = getExtendedNode(childNode);

				// Process old full node
				processFullNode(childNode);

				// Add the new node for parent reference
				curNode.AddChildren(i + 1, newNode);

				// Down to low layer
				if (elem.compareTo(curNode.getKey(i)) < 0) {
					curNode = childNode;
				} else {
					curNode = newNode;
				}
				i = 0;
				continue;
			}

			// Down to child node
			if (!childNode.isNull()) {
				curNode = childNode;
				i = 0;
				continue;
			}

			// Insert the element in current node
			addElemToNode(curNode, elem, i);
			return;
		}

	}

	private BTNode getExtendedNode(BTNode fullNode) {
		BTNode newNode = new BTNode();
		newNode.number = t - 1;
		newNode.isLeaf = fullNode.isLeaf;
		for (int i = 0; i < t; i++) {
			if (i != t - 1) {
				newNode.AddKey(i, fullNode.getKey(t + i));
			}
			newNode.AddChildren(i, fullNode.getChildren(t + i));
		}
		return newNode;
	}

	// Should be called after calling getExtendedNode()
	private void processFullNode(BTNode fullNode) {
		fullNode.number = t - 1;
		for (int i = t - 1; i >= 0; i--) {
			fullNode.removeKey(t + i - 1);
			fullNode.removeChildren(t + i);
		}
	}

	@Override
	public String toString() {
		if (root == null)
			return "NULL";

		StringBuilder sb = new StringBuilder();

		LinkedList<BTNode> queue = new LinkedList<BTNode>();
		queue.push(root);

		BTNode tem = null;
		while ((tem = queue.poll()) != null) {
			for (BTNode node : tem.children) {
				if (!node.isNull())
					queue.offer(node);
			}
			sb.append(tem.toString() + "\n");
		}
		return sb.toString();
	}

	public static void main(String[] args) {
		BTree<Character> tree = new BTree<Character>(3);
		System.out.println(tree);
		Character[] cL = { 'D', 'E', 'F', 'A', 'C', 'B', 'Z', 'H', 'I', 'J' };
		for (int i = 0; i < cL.length; i++) {
			tree.insertElem(cL[i]);
			System.out.println("After insert the: " + cL[i]);
			System.out.println(tree);
		}
	}
output
===================
NULL
After insert the: D
[N: 1] [values: D,  ] [ children: NullNode, NullNode, ] [childrenSize: 2] [ isLeaf: true]

After insert the: E
[N: 2] [values: D, E,  ] [ children: NullNode, NullNode, NullNode, ] [childrenSize: 3] [ isLeaf: true]

After insert the: F
[N: 3] [values: D, E, F,  ] [ children: NullNode, NullNode, NullNode, NullNode, ] [childrenSize: 4] [ isLeaf: true]

After insert the: A
[N: 4] [values: A, D, E, F,  ] [ children: NullNode, NullNode, NullNode, NullNode, NullNode, ] [childrenSize: 5] [ isLeaf: true]

After insert the: C
[N: 5] [values: A, C, D, E, F,  ] [ children: NullNode, NullNode, NullNode, NullNode, NullNode, NullNode, ] [childrenSize: 6] [ isLeaf: true]

After insert the: B
[N: 1] [values: D,  ] [ children: NotNullNode, NotNullNode, ] [childrenSize: 2] [ isLeaf: false]
[N: 2] [values: A, C,  ] [ children: NullNode, NullNode, NullNode, ] [childrenSize: 3] [ isLeaf: true]
[N: 2] [values: E, F,  ] [ children: NullNode, NullNode, NullNode, ] [childrenSize: 3] [ isLeaf: true]

After insert the: Z
[N: 1] [values: D,  ] [ children: NotNullNode, NotNullNode, ] [childrenSize: 2] [ isLeaf: false]
[N: 2] [values: A, C,  ] [ children: NullNode, NullNode, NullNode, ] [childrenSize: 3] [ isLeaf: true]
[N: 3] [values: E, F, Z,  ] [ children: NullNode, NullNode, NullNode, NullNode, ] [childrenSize: 4] [ isLeaf: true]

After insert the: H
[N: 1] [values: D,  ] [ children: NotNullNode, NotNullNode, ] [childrenSize: 2] [ isLeaf: false]
[N: 2] [values: A, C,  ] [ children: NullNode, NullNode, NullNode, ] [childrenSize: 3] [ isLeaf: true]
[N: 4] [values: E, F, H, Z,  ] [ children: NullNode, NullNode, NullNode, NullNode, NullNode, ] [childrenSize: 5] [ isLeaf: true]

After insert the: I
[N: 1] [values: D,  ] [ children: NotNullNode, NotNullNode, ] [childrenSize: 2] [ isLeaf: false]
[N: 2] [values: A, C,  ] [ children: NullNode, NullNode, NullNode, ] [childrenSize: 3] [ isLeaf: true]
[N: 5] [values: E, F, H, I, Z,  ] [ children: NullNode, NullNode, NullNode, NullNode, NullNode, NullNode, ] [childrenSize: 6] [ isLeaf: true]

After insert the: J
[N: 2] [values: D, H,  ] [ children: NotNullNode, NotNullNode, NotNullNode, ] [childrenSize: 3] [ isLeaf: false]
[N: 2] [values: A, C,  ] [ children: NullNode, NullNode, NullNode, ] [childrenSize: 3] [ isLeaf: true]
[N: 2] [values: E, F,  ] [ children: NullNode, NullNode, NullNode, ] [childrenSize: 3] [ isLeaf: true]
[N: 3] [values: I, J, Z,  ] [ children: NullNode, NullNode, NullNode, NullNode, ] [childrenSize: 4] [ isLeaf: true]
3
0
分享到:
评论
3 楼 970655147 2016-01-10  
hi 博主你好, 我仿照你的这个代码写了一个, 发现了一个bug, 就是在"if (root.isFull())"满足条件的语句中, 不应该直接return, 而是应该继续向下走, 将元素ele插入到当前BTree中


引用

After insert the: C 
[N: 5] [values: A, C, D, E, F,  ] [ children: NullNode, NullNode, NullNode, NullNode, NullNode, NullNode, ] [childrenSize: 6] [ isLeaf: true] 
 
After insert the: B 
[N: 1] [values: D,  ] [ children: NotNullNode, NotNullNode, ] [childrenSize: 2] [ isLeaf: false] 
[N: 2] [values: A, C,  ] [ children: NullNode, NullNode, NullNode, ] [childrenSize: 3] [ isLeaf: true] 
[N: 2] [values: E, F,  ] [ children: NullNode, NullNode, NullNode, ] [childrenSize: 3] [ isLeaf: true] 

像上面的添加"B" 的过程中, 并没有将"B"添加进去
2 楼 cfczdws 2015-05-06  
看了受益匪浅,学习
1 楼 blackproof 2013-03-08  
多谢学习了

相关推荐

    完整B树算法Java实现代码

    在计算机科学中,B树(B-tree)是一种自平衡的多路查找树,它的设计目的是为了优化磁盘或网络存储环境下的数据检索效率。...在Java中实现B树需要理解其数据结构特点,并适当地处理插入、查找和删除操作,确保树的平衡。

    B+树算法的Java实现方法研究.zip

    本研究主要探讨如何在Java编程语言中实现B+树算法,以理解其原理并应用到实际项目中。 B+树是一种自平衡的多路查找树,其特点包括以下几点: 1. **分层结构**:B+树具有层级关系,根节点位于最顶层,叶子节点位于...

    B+树算法的Java实现方法研究.pdf

    总之,B+树算法的Java实现是一种技术挑战,它需要开发者具备对数据结构和算法的深入理解,以及对Java语言特性的熟悉。通过研究和实践,可以加深对B+树在数据库索引构建和文件系统管理中应用的理解,并能够开发出性能...

    B树的Java实现

    **B树(B-tree)是一种自平衡的查找树...通过分析`BTree`这个文件,我们可以看到B树的具体实现细节,包括节点结构、插入、查找和删除的算法。如果你需要进一步的帮助,可以研究这个文件或者在给定的博客中寻找答案。

    k-means算法Java实现

    为了提高算法的效率,可以采用一些优化策略,如Elkan算法利用三角不等式减少距离计算,或者使用B++树等数据结构加速近邻搜索。此外,k-means对初始质心的选择很敏感,可以考虑使用k-means++算法来更合理地选择初始点...

    R树的Java实现

    与传统的B树或B+树不同,R树允许每个节点包含多个边界,这些边界形成一个多边形区域,覆盖了该节点内所有子节点的数据点。通过这种方式,R树能够在高维空间中有效地减少索引的存储开销和查询时间。 2. R树的工作...

    山东大学数据结构实验B-树(java实现)

    Java实现B-树时,首先需要定义一个BTreeNode类来表示树的节点。这个类通常包含键的数组、子节点的数组以及一些辅助方法,如查找键的位置、分裂节点等。节点中的键和子节点的数量应该满足B-树的性质:每个节点最多...

    B+ tree的java实现

    下面将详细讨论如何用Java实现B+树。 首先,B+树的节点分为两种类型:内部节点(或索引节点)和叶子节点。内部节点存储键值,不存储数据,而叶子节点则同时存储键值和对应的数据。在Java实现中,我们通常会创建两个...

    B-tree 树的 Java实现

    通过理解B树的数据结构原理,并结合Java编程语言特性,我们可以构建一个高效且功能完备的B树实现。这样的实现对于学习数据结构、开发数据库系统或是优化磁盘上的数据访问都非常有价值。在实际项目中,B树常用于文件...

    Prim算法Java实现

    ### Prim算法Java实现 #### 背景与概念 Prim算法是一种用于寻找加权无向图中的最小生成树(Minimum Spanning Tree, MST)的经典算法。一个无向加权图由一组顶点和一组边组成,每条边都有一个权重值。在本任务中,...

    java多叉树的实现和遍历输出

    本篇文章将深入探讨如何在Java中实现多叉树以及其遍历方法。 首先,我们需要定义一个多叉树节点类。这个类通常包含一个数据字段来存储节点值,以及一个ArrayList或LinkedList等动态数组来存储子节点。以下是一个...

    java实现的数据结构与算法

    《Java实现的数据结构与算法》是一本全面介绍数据结构和算法实现的书籍,以Java语言为载体,涵盖了面向对象程序设计的基本概念和特性,并深入探讨了数据结构与算法的方方面面,包括各种数据结构的基本概念、算法的...

    AdaBoost算法java实现统计学习方法例子

    在Java实现中,数据结构的选择、优化和错误处理也是关键部分。通常,样本集可以表示为二维数组或`ArrayList`,特征和类别存储在对应的位置。弱分类器的训练过程可能涉及特征选择策略,如基尼指数或信息增益。同时,...

    数据结构与算法(JAVA语言版)

    常见的树结构有二叉树、平衡二叉树(如AVL树和红黑树)、B树和B+树等。Java的`java.util.TreeSet`和`java.util.TreeMap`基于红黑树实现。 8. **图**:图由节点(顶点)和连接节点的边构成,用于表示复杂的关联关系...

    B_Tree 的JAVA实现

    总的来说,理解B树的原理并用Java实现B树的基本操作,需要掌握数据结构的基本概念,理解B树的特性,并能够灵活运用这些特性来编写代码。在实际应用中,根据具体需求调整B树的阶数m,可以优化空间效率和操作性能。...

    B树实现的文件索引 java版

    在Java实现B树的文件索引过程中,我们需要关注以下几个关键步骤: 1. **节点类设计**:首先,创建一个表示B树节点的类,包括关键字、子节点指针以及必要的辅助方法如分裂、合并等。 2. **B树类设计**:接着,设计B...

    Java实现汉诺塔递归算法详解

    以下是一个简单的Java程序来实现汉诺塔问题的解决方案: ```java public class Hanoi { public static void moveTower(int n, char from, char inter, char to) { if (n == 1) { // 基本情况:只剩一个盘子时,...

    B.rar_B树_B树 java_b 树 索引_树 搜索

    **B树概述** ...理解和掌握B树的原理及其Java实现,对于提升数据结构和算法能力,优化存储系统性能具有重要意义。在实际应用中,根据具体需求选择合适的B树变种,如B+树、B*树等,可以进一步提高性能。

    KD树java实现

    ### KD树Java实现详解 #### 一、简介 在计算机科学领域,KD树(K-Dimensional Tree)是一种用于多维空间的数据结构,主要用于快速解决最近邻搜索问题以及其他类似的问题,如范围查询等。本篇文章将深入探讨一篇...

    数据结构与算法Java实现.zip

    逻辑结构:描述数据元素之间的逻辑关系,如线性结构(如数组、链表)、树形结构(如二叉树、堆、B树)、图结构(有向图、无向图等)以及集合和队列等抽象数据类型。 存储结构(物理结构):描述数据在计算机中如何...

Global site tag (gtag.js) - Google Analytics