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

Tree 2-3-4 平衡搜索树

阅读更多

2-3-4 平衡树是一种搜索树。每个节点可能会有2,3,4个子节点,对应可能会有1,2,3个数据。子节点数=数据数 + 1,不可能有空节点。

插入数据时,数据均插入叶子节点,树在向下遍历以得到恰当的叶子节点时,每遇到满的节点,则进行节点分裂,当分裂向上累积致根节点位置,根节点分裂,所有叶子节点的层高都增加一层,以此原理来保证树的平衡。

此树没有实现删除数据的算法,如果需要,可考虑将数据标志为作废的方式,以避免真正的删除时的复杂。

插入的数据为了简便起见,假设均为Integer,且不会重复。

方法ordinal是升序打印,为的是测试。

Tree.main 函数提供一个简短的测试。

Node类为辅助类,管理单个节点的操作。

Tree为2-3-4树,管理节点与节点之间的操作。其他的平衡数可以参见红黑树

关于简单的二叉搜索树,请参见(Tree )。

class Node {
	private Integer[] values = new Integer[3];	//存放数据
	private Node[] children = new Node[4];	//存放子节点引用
	private int size;	//当前有效数据数量
	private Node parent;	//当前节点的父节点
	Node() {}
	Node(Integer i) {
		values[0] = i;
		size = 1;
	}

	int insert(Integer value) {	//将数据插入有序数组
		assert size < values.length;
		int pos = size;
		while(pos > 0 && values[pos - 1] > value) {
			values[pos] = values[pos - 1];
			pos--;
		}
		values[pos] = value;
		size ++;
		return pos;
	}

	Node getChildByValue(Integer value) {	//根据给定数据的关键字,寻找恰当的子节点
		for(int i=0; i<size; i++) {
			if(values[i] > value) return children[i];
		}
		return children[size];
	}
	
	//根据给定子节点的索引值,得到对应的子节点
	Node getChildByIndex(int index) { return children[index]; }
	
	int find(Integer value) {
		for(int i=0; i<size; i++) {
			if(values[i].equals(value)) return i; 
		}
		return -1;
	}

	Integer removeMax() { return values[--size]; }	//删除当前节点内最大的数据,并返回之
	
	//根据给定子节点的索引值,删除与其的对应节点之间的父子关系
	Node removeChild(int index) {	
		Node result = children[index];
		if(result != null)result.parent = null;
		children[index] = null;
		return result;
	}
	
	//在当前节点中,在指定的索引值之后插入相应的子节点,之后的原有的子节点全部向后平移
	void insertChild(int index, Node child) {
		for(int i=size; i>index + 1; i--) children[i] = children[i-1];
		children[index+1] = child;
		if(child != null)child.parent = this;
	}
	
	//在当前节点中,在指定的索引值的位置置入相应子节点
	void setChild(int index, Node child) {
		children[index] = child;
		if(child != null) child.parent = this;
	}

	int size() { return size; }
	
	boolean isFull() { return size ==  values.length; }

	boolean isLeaf() { return children[0] == null; }

	Node getParent() { return parent; }

	Integer getValue(int index) { return values[index]; }

}
	
class Tree {
	private Node root = new Node();	//根节点
	public void insert(Integer value) {	//将数据插入树中
		Node current = root;	//从根向下开始寻找恰当的叶子节点
		while(!current.isLeaf()) {
			if(current.isFull()) current = split(current);	//如果下行过程遇到满的节点,分裂之
			current = current.getChildByValue(value);	
		}
	
		if(current.isFull()) {	//如果最终找到的叶子节点是满的,先分裂之
			current = split(current);	
			current = current.getChildByValue(value);	
		}
		current.insert(value);	//在叶子节点插入数据
	}

	public boolean contains(Integer value) {
		Node current  = root;
		while(!current.isLeaf()) {
			if(current.find(value) != -1) return true;
			current = current.getChildByValue(value);
		}
		return current.find(value) != -1;
	}

	public void ordinal() {	//安升序排列输入树中所有的数据
		ordinal(root);
	}

	private void ordinal(Node current) {
		for(int i=0; i<current.size(); i++) {
			if(!current.isLeaf()) ordinal(current.getChildByIndex(i));
			System.out.println(current.getValue(i));
		}
		if(!current.isLeaf()) ordinal(current.getChildByIndex(current.size()));
	}

	private Node split(Node current) {	//分裂算法
		Node parent = current.getParent();	//寻找当前节点的父节点
		if(parent == null) parent = new Node();
		//将当前节点拆分成左节点,右节点,中间的数据,其右节点是个新节点
		Node nodeLeft = current;
		Node nodeRight = new Node(current.removeMax());
		Integer middle = current.removeMax();
		//断开当前节点中的第2,3子节点,并加入右字节中
		Node child1 = nodeLeft.removeChild(2);
		Node child2 = nodeLeft.removeChild(3);
		nodeRight.setChild(0,child1);
		nodeRight.setChild(1,child2);

		int index = parent.insert(middle);	//将中间的数据加入其父节点,并得到插入的位置
		
		if(current == root) {	//如果当前节点是根节点,则在新的父节点中加入左右节点
			parent.setChild(0,nodeLeft);
			parent.setChild(1,nodeRight);
			root = parent; //重置根节点
		} else parent.insertChild(index,nodeRight);	//否则,在父节点中指定位置后插入右节点

		return parent;	//返回父节点
	}

	public static void main(String[] args) {
		Tree t = new Tree();
		t.insert(5);
		t.insert(6);
		t.insert(7);
		t.insert(8);
		t.insert(9);
		t.insert(10);
		t.insert(30);
		t.insert(50);
		t.insert(11);
		t.insert(17);
		t.insert(19);
		t.insert(54);
		t.insert(66);
		t.insert(72);
		t.insert(89);
		t.insert(92);
		t.insert(40);
		t.insert(28);
		t.insert(13);
		t.insert(14);
		t.insert(16);
		t.ordinal();
	}
}

 

5
1
分享到:
评论
3 楼 arust 2008-05-28  
学习一下
2 楼 dboylx 2008-04-29  
支持~~~学习中,希望楼主继续~~
1 楼 桔红糕 2008-04-20  
oh my god一看就觉得有点头晕!!
但是~~
我一定认真研读,有不明白的地方还请shen老师耐心教诲!

相关推荐

    2-3-tree-master.zip_2-3树建立

    通过分析"2-3-tree-master.zip"的代码,我们可以深入理解2-3树的各种操作的实现细节,例如节点的创建、插入、删除和查找方法,以及树的平衡调整策略。这些实现可以帮助我们更好地应用和优化这种数据结构。

    2-3 tree (Introduction of Algorithm)

    搜索操作在2-3树中的进行方式与普通二叉搜索树非常相似。插入或删除操作的执行需要描述的是如何更新内部节点存储的键的副本,但这部分细节比较直接明了,这里就留给读者自己探究。 插入操作开始于执行一个搜索,以...

    B-Tree B-Tree

    B-Tree(B树),是一种自平衡的树数据结构,它能够保持数据排序,常用于数据库和文件系统中。B-Tree的主要特性是节点可以拥有多个子节点,通常远多于二叉树。这种数据结构允许高效地在大型数据集上进行查找、插入和...

    資料結構2-3-4樹

    总而言之,从AVL树到2-3树,再到2-3-4树,自平衡树结构展现了从二叉搜索树到多路搜索树的演进,每一步都体现了提高数据操作效率和优化树平衡的不懈追求。它们通过严格的平衡机制和精心设计的节点分裂与旋转规则,...

    2-3-tree:2-3树数据结构的简单演示

    在给定的压缩包文件"2-3-tree-master"中,很可能包含了C++实现2-3树的源代码。这个代码库可能包括了节点类的定义、插入、查找和删除等操作的实现,以及相关的测试用例,帮助用户理解和学习2-3树的工作原理。 通过...

    tree-java.rar_tree_二叉搜索树

    二叉搜索树(Binary Search Tree, BST)是一种特殊的二叉树数据结构,它具有以下特性: 1. **每个节点都包含一个键(key)、一个关联的值、一个指向左子节点的引用和一个指向右子节点的引用**。 2. **键的值大于左...

    B-树的实现,B-树的分析,B-树的代码

    B-树是一种多路搜索树(M-way Search Tree),其中每个节点可以有多个子节点。它由一系列完全填充的节点组成,这些节点包含键值、指针以及可能还有其他数据字段。B-树的一个重要特性是所有叶子节点都位于同一层,这...

    some-of-the-binary-tree-algorithm..zip_The Tree

    【描述】提到了其中包含的“超级经典算法”,暗示了我们将探讨的算法包括但不限于二叉查找树(Binary Search Tree, BST)、AVL树、红黑树(Red-Black Tree)、B树、Trie树以及平衡二叉搜索树等。 1. **二叉查找树...

    B.rar_B-树索引_B树_b tree_b tree java_java B-Tree

    1. **B-树结构**:B-树是一种自平衡的多路搜索树,每个节点可以有多个子节点,这些子节点通常称为分支或指针。B-树的每个节点包含一个键值集合和对应的子树指针集合。 2. **度**:B-树的度指的是每个节点最多能有的...

    前端开源库-node-interval-tree

    节点间隔树基于二叉搜索树(Binary Search Tree, BST)的概念,但每个节点不仅包含一个值,还包含一个区间。这种数据结构的设计使得在O(log n)的时间复杂度内完成区间查询、插入和删除操作成为可能。区间查询能够...

    CHAZHAO.zip_2-3查找树

    相比于普通二叉排序树,2-3查找树在插入新节点时能更好地保持平衡,减少了深度过深的情况,从而提高了性能。 在实现2-3查找树的过程中,我们需要处理各种边界情况。例如,插入一个新节点时,如果树为空,新节点就是...

    Python库 | red-black-tree-mod-1.11.tar.gz

    3. **时间复杂度**:由于红黑树的自平衡性质,插入、删除和查找操作的时间复杂度都是O(log n),其中n是树中的节点数。这使得红黑树在处理大量数据时表现优秀。 4. **应用**:红黑树在多种场景下被广泛使用,如C++ ...

    B-树的源代码

    B-树,全称为平衡多路搜索树(Balanced Multiway Search Tree),是数据库和文件系统中常用的一种数据结构,其设计目标是为了在磁盘等慢速存储设备上高效地进行数据检索。B-树是一种自平衡的树,能够保持数据排序性...

    binary-tree-traversal-binary-tree.zip_tree

    查找操作在二叉搜索树中尤为高效,因为它满足左子树的所有节点值小于根节点,右子树的节点值大于根节点,这使得查找可以在对数时间内完成。插入和删除操作则需要维护树的平衡,以防止退化成链表,降低效率。常见的...

    binary-tree-master (3).zip

    在二叉树的实现中,常见的数据结构包括二叉搜索树(BST)、完全二叉树、满二叉树、平衡二叉树(如AVL树和红黑树)等。每个都有其特定的性质和操作,如插入、删除、查找等。C语言实现这些操作时,需要考虑指针的使用...

    2_3_tree.rar_23tree_23树实现_2_3_tree

    2-3树在实际应用中主要用于数据库索引、文件系统等场景,它的优点在于插入和删除操作通常比二叉搜索树更快,因为它始终保持平衡。然而,与红黑树、AVL树等其他自平衡树相比,2-3树在实际编程中可能不太常见,因为...

    semester-work-b-tree-11-004:平衡搜索树

    它是什么样的(平衡树,线性列表等)? 在哪里以及如何使用(应用程序)? 可以对其执行哪些操作(搜索,删除,添加,插入等)? 操作的理论复杂度是什么( O(log(n))搜索, O(n^2)插入等)? 有关该项目的其他...

    B- B-树算法实现

    3. 平衡:B-树始终保持平衡,这意味着所有叶子节点都位于相同深度,确保了搜索效率。 4. 插入与删除:B-树的插入和删除操作需要考虑整个树的平衡,可能涉及节点分裂、合并和数据移动。 在C语言实现B- B-树时,首先...

    KD-Tree C++程序

    **KD-Tree(K-Dimensional Tree)是一种在高维空间中组织数据的树形数据结构,主要用于快速查找、分类和最近邻搜索等操作。在C++中实现KD-Tree可以帮助我们理解和应用这种数据结构,特别是在处理多维数据时,如在...

    Two-fork-tree-basic-operation.zip_operation

    对于有序二叉树(如二叉搜索树),从根节点开始,如果目标值小于当前节点,则在左子树中继续搜索;反之,在右子树中搜索。 4. **删除节点**: 删除节点是最复杂的操作之一,因为它可能涉及重新排列子树。根据要...

Global site tag (gtag.js) - Google Analytics