`
baby69yy2000
  • 浏览: 187859 次
  • 性别: Icon_minigender_1
  • 来自: 自己输入城市...
社区版块
存档分类
最新评论

二叉排序树的实现

    博客分类:
  • Util
阅读更多
最适合用STree排序的是不可变类,不可变类的主要特征是它的对象的属性不能被修改.
public class Customer  implements Comparable<Object>{
	private final String name;
	private final int age;
...
}


二叉排序树操作的复杂度
最好情况: 完全树
最坏情况: 在二叉排序树为退化树时,add()和remove()处于最坏情况,相当于一个链表,可以通过红黑树消除最坏情况.

Iterator接口

package BinarySearchTree;

public interface Iterator<T> {
	public boolean hasNext();
	public T next();
	public void remove();
}


package BinarySearchTree;
import java.util.ConcurrentModificationException;
import java.util.NoSuchElementException;

public class STree<T> implements Cloneable {
	
	/**结点内部类*/
	private static class STNode<T> {
		T nodeValue;
		STNode<T> left, right, parent;
		
		/**结点类构造函数*/
		public STNode(T item, STNode<T> parentNode) {
			nodeValue = item;
			left = null;
			right = null;
			parent = parentNode;
		}
	}
	
	/**二叉搜索树类成员变量*/
	private STNode<T> root;
	private int treeSize;
	private int modCount;
	
	/**二叉搜索树类构造函数*/
	public STree() {
		root = null;
		treeSize = 0;
		modCount = 0;
	}
	
	/**插入方法*/
	public boolean add(T item) {
		STNode<T> t = root, parent = null, newNode;
		int orderValue = 0;
		
		// 循环终止条件在一个空的子树上
		while(t != null) {
			// 更新父结点的引用
			parent = t;
			// 比较item与当前结点的值
			orderValue = ((Comparable<T>)item).compareTo(t.nodeValue);
			// 比较item与当前结点的值,小于零往左走,否则向右走,等于零将不能插入新值
			if(orderValue == 0)
				return false;
			else if(orderValue < 0)
				t = t.left;
			else
				t = t.right;
		}
		// 创建新结点
		newNode = new STNode<T>(item, parent);
		
		// 下面几句是父结点与子结点的连接操作
		if(parent == null)
			// 这是第一个被添加的结点,使它成为根结点
			root = newNode;
		else if(orderValue < 0)
			// 连接新结点作为父结点的左孩子
			parent.left = newNode;
		else
			// 连接新结点作为父结点的右孩子
			parent.right = newNode;
		
		// 增加tree size and modCount
		treeSize++;
		modCount++;
		
		return true;
	}
	
	/**定位结点*/
	public T find(T item) {
		STNode<T> t = findNode(item);
		T value = null;
		if (t != null)
			value = t.nodeValue;
		return value;
	}
	
	private STNode<T> findNode(Object item) {
		STNode<T> t = root;
		int orderValue;
		while(t != null) {
			orderValue = ((Comparable<T>)item).compareTo(t.nodeValue);
			if(orderValue == 0)
				return t;
			else if(orderValue < 0)
				t = t.left;
			else
				t = t.right;
		}
		return null;
	}
	
	/**删除结点*/
	public boolean remove(Object item) {
		STNode<T> dNode = this.findNode(item);
		if(dNode == null)
			return false;
		removeNode(dNode);
		treeSize--;
		modCount++;
		return true;
	}
	
	private void removeNode(STNode<T> dNode) {
		if(dNode == null)
			return;
		
		// dNode: 待删除结点
		// pNode: 待删除结点的父结点
		// rNode: 待删除结点的替换结点
		STNode<T> pNode, rNode;
		
		pNode = dNode.parent;
		
		// 待删除的结点至少具有一棵空子树
		if(dNode.left == null || dNode.right == null) {
			// 找替换结点
			if(dNode.right == null)
				rNode = dNode.left;
			else
				rNode = dNode.right;
			
			if(rNode != null)
				rNode.parent = pNode;
			
			// 连接操作
			if(pNode == null)
				root = rNode;
			else if(((Comparable<T>)dNode.nodeValue).compareTo(pNode.nodeValue) < 0)
				pNode.left = rNode;
			else
				pNode.right = rNode;
		
		// 待删除的结点具有两个非空子树
		}else {
			// pOfRNode: 替换结点的父结点
			STNode<T> pOfRNode = dNode;
			
			rNode = dNode.right;
			pOfRNode = dNode;
			
			while(rNode.left != null) {
				pOfRNode = rNode;
				rNode = rNode.left;
			}
			
			dNode.nodeValue = rNode.nodeValue;
			
			if(pOfRNode == dNode)
				dNode.right = rNode.right;
			else
				pOfRNode.left = rNode.right;
			
			if(rNode.right != null)
				rNode.right.parent = pOfRNode;
			
			dNode = rNode;
		}
		dNode = null;
	}// end removeNode~
	
	/** 返回最小值*/
	public T first() {
		STNode<T> nextNode = root;
		if(nextNode == null)
			return null;
		while(nextNode.left != null)
			nextNode = nextNode.left;
		return nextNode.nodeValue;
	}
	
	/** 返回最大值*/
	public T last() {
		STNode<T> nextNode = root;
		if(nextNode == null)
			return null;
		while(nextNode.right != null)
			nextNode = nextNode.right;
		return nextNode.nodeValue;
	}
	
	/**清除树*/
	public void clear() {
		this.deleteTree(root);
		root = null;
		treeSize = 0;
	}
	
	private void deleteTree(STNode<T> t) {
		if(t != null) {
			deleteTree(t.left);
			deleteTree(t.right);
			t = null;
		}
	}
	
	public Object clone() {
		STree<T> copy = null;
		try {
			copy = (STree<T>)super.clone();
		}catch (CloneNotSupportedException cnse){
			throw new InternalError(); 
		}
		copy.root = copyTree(root);
		// return the cloned object
		return copy;
	}
	
	/**后根遍历由底向上复制一棵树*/
	private static<T> STNode<T> copyTree(STNode<T> t) {
		STNode<T> newLeft, newRight, newNode;
		
		if(t == null)
			return null;
		
		newLeft = copyTree(t.left);
		newRight = copyTree(t.right);
		
		newNode = new STNode<T>(t.nodeValue, null);
		newNode.left = newLeft;
		newNode.right = newRight;
		
		if(newLeft != null)
			newLeft.parent = newNode;
		if(newRight != null)
			newRight.parent = newNode;
		
		return newNode;
	}

	public boolean contains(Object item) {
		STNode<T> t = findNode(item);
		return (t == null) ? false : true;
	}
	
	public int size() {
		return treeSize;
	}
	
	public boolean isEmpty() {
		return treeSize == 0;
	}
	
	public Object[] toArray() {
		
		Iterator<T> iter = this.iterator();
		Object[] arr = new Object[treeSize];
		int i = 0;
		while(iter.hasNext()) {
			arr[i] = iter.next();
			i++;
		}
		return arr;
	}
	
	public String toString() {
		int i;
		String str = "[";
		Iterator<T> iter = this.iterator();
		for (i = 0; i < treeSize; i++) {
			str += iter.next();
			if(i < treeSize - 1)
				str += ", ";
		}
		str += "]";
		return str;
	}

	/**二叉搜索树跌代器的公共方法*/
	public Iterator<T> iterator() {
		return new MyIterator();
	}
	
	/**MyIterator内部类*/
	private class MyIterator implements Iterator<T> {
		private int expectedModCount = modCount;
		private STNode<T> tmp = null;
		private STNode<T> nextNode = null;

		MyIterator() {
			nextNode = root;
			if(nextNode != null) {
				while(nextNode.left != null)
					nextNode = nextNode.left;
			}
		}
		
		public boolean hasNext() {
			return nextNode != null;
		}
		
		public T next() {
			checkIteratorState();
			if(nextNode == null)
				throw new NoSuchElementException(
						"Iteration has no more elements");
			tmp = nextNode;
			STNode<T> p;
			
			if(nextNode.right != null) {
				nextNode = nextNode.right;
				while(nextNode.left != null)
					nextNode = nextNode.left;
			}else {
				p = nextNode.parent;
				while(p != null && nextNode == p.right) {
					nextNode = p;
					p = p.parent;
				}
				nextNode = p;
			}
			
			return tmp.nodeValue;
		}
		
		public void remove()
	      {
	         // check for a missing call to next() or previous()
	         if (tmp == null)
	            throw new IllegalStateException(
	               "Iterator call to next() " +
	               "required before calling remove()");

	         // make sure our state is good
	         checkIteratorState();

				// if lastReturned has two children, the replacement node
				// during deletion is nextNode. the value in nextNode
				// is copied to lastReturned. nextNode must be
				// lastReturned
				if (tmp.left != null && tmp.right != null)
					 nextNode = tmp;
	         removeNode(tmp);

	         // list has been modified
	         modCount++;
	         expectedModCount = modCount;

	         // we did a deletion. indicate this by setting lastReturned
	         // to null and decrementing treeSize
	         tmp = null;
	         treeSize--;
	      }
		
		 private void checkIteratorState() {
	         if (expectedModCount != modCount)
	            throw new ConcurrentModificationException(
	               "Inconsistent iterator");
		 }
		 
	}//end MyIterator~

}//end STree~


测试类

package BinarySearchTree;

// 要实现Comparable接口,然后重写compareTo方法
public class Customer  implements Comparable<Object>{
	private String name;
	private int age;
	
	public Customer(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}
	
	public void setName(String name) {
		this.name = name;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
	public int compareTo(Object o) {
		Customer other = (Customer)o;
		
		if(this.name.compareTo(other.name) > 0)
			return 1;
		if(this.name.compareTo(other.name) < 0)
			return -1;
		
		if(this.age > other.age)
			return 1;
		if(this.age < other.age)
			return -1;
		return 0;
	}

	public static void main(String[] args) {
		STree<Customer> sT = new STree<Customer>();
		Customer c1 = new Customer("Tom", 32);
		Customer c2 = new Customer("Jack", 12);
		Customer c3 = new Customer("Lucy", 22);
		sT.add(c1); sT.add(c1);
		sT.add(c2);
		sT.add(c3);
		Iterator<Customer> it = sT.iterator();
		while(it.hasNext()) {
			Customer c = it.next();
			System.out.println(c.getName() + " " + c.getAge());
		}
		
		Customer minAge = sT.first();
		System.out.println("minAge: " + minAge.getName() + " " + minAge.getAge());
		
		Customer f = sT.find(c2);
		f.setAge(42);
		System.out.println("find: " + f.getName() + " " + f.getAge());
		
		System.out.println(sT.contains(c3));
		
		sT.clear();
		System.out.println(sT.size());
	}

	

	

}
































































分享到:
评论

相关推荐

    二叉排序树实现教师成果管理系统源码

    除了二叉排序树的实现,此系统还集成了基本的文件操作,这是为了将教师成果数据持久化存储。文件操作通常包括: - **数据保存**:将当前二叉排序树中的所有节点信息序列化,写入到磁盘文件中,以便下次启动系统时能...

    二叉排序树实现

    VC6.0环境下,使用C++/C编写,实现了二叉排序树的基本功能。

    数据结构实验之二叉排序树

    在"数据结构实验之二叉排序树"中,我们主要关注的是如何利用二叉排序树实现动态查找、插入和删除操作。动态查找是指在数据结构中搜索特定值的过程,对于二叉排序树,这个过程通常从根节点开始,如果目标值小于当前...

    二叉排序树 学生管理系统

    二叉排序树实现的学生管理 有创建插入 删除 查找等功能

    Java实现二叉排序树

    在Java中实现二叉排序树,我们通常会定义一个`Node`类来表示树的节点,它包含键、值以及左右子节点的引用。例如: ```java class Node { int key; Object value; Node left, right; public Node(int item) { ...

    基于二叉排序树的电话本C语言系统

    本文档将详细介绍一个基于二叉排序树(Binary Search Tree, BST)实现的电话本系统。该系统采用C语言编写,主要功能包括:添加联系人、查找联系人、删除联系人以及更新联系人信息等。通过使用二叉排序树的数据结构,...

    二叉排序树C实现代码

    二叉排序树C语言的简单实现,包含如下操作: 1.创建二叉排序树; 2.销毁二叉排序树; 3.清空二叉排序树; 4.插入指点结点至二叉排序树; 5.删除二叉排序树指点结点; 5.获取二叉排序树指定结点; 6.获取二叉排序树根...

    二叉排序树C++实现

    二叉排序树的C++实现可能涉及类的定义,包括节点结构、插入、删除、搜索和遍历的方法。文件"Binary sort Tree"可能包含了这些实现细节,具体代码会展示如何创建和操作二叉排序树。通过阅读和理解这些代码,你可以...

    二叉排序树插入

    二叉排序树插入算法 二叉排序树插入是指在二叉排序树中插入新的数据元素的过程。二叉排序树是一种特殊的二叉树,它的每个结点的关键字都大于左子树的关键字,小于右子树的关键字。因此,在插入新的数据元素时,需要...

    二叉排序树实现 数据结构 严蔚敏

    二叉排序树实现 数据结构 c++ 严蔚敏 完全是课本上的

    二叉排序树_17281183_刘梦婷_leavingtbk_二叉排序树_

    在给定的压缩文件"二叉排序树_17281183_刘梦婷"中,可能包含了实现这些功能的代码示例或练习题目,用于帮助学习者理解和掌握二叉排序树的操作。 通过理解和熟练运用二叉排序树,我们可以有效地处理各种数据结构问题...

    数据结构课程设计二叉排序树的实现

    ### 数据结构课程设计二叉排序树的实现 #### 一、二叉排序树的基本概念 二叉排序树(Binary Search Tree, BST),又称二叉查找树或有序二叉树,是一种特殊的二叉树,其特点在于对于任意节点而言,其左子树中的所有...

    数据结构课程设计 二叉排序树与平衡二叉排序树

    在这个课程设计中,我们将重点探讨如何利用二叉链表作为存储结构来实现二叉排序树,并进一步研究平衡二叉排序树的概念。 首先,二叉排序树的特性是每个节点的左子树只包含小于该节点的元素,而右子树则包含大于或...

    二叉排序树与文件操作

    【二叉排序树与文件操作】 功能要求: (1)从键盘输入一组学生记录建立二叉排序树; (2)二叉排序树存盘; (3)由文件恢复内存的二叉排序树; (4)中序遍历二叉排序树; (5)求二叉排序树深度; (6)求二叉...

    实现二叉排序树的各种算法

    在"实现二叉排序树的各种算法"的实验中,通常会涉及以下关键算法: 1. **树的构建**:从一组有序或无序的数据中构建二叉排序树。这可以通过遍历数据并按照二叉排序树的规则逐个插入节点来实现。 2. **插入操作**:...

    数据结构课程设计实现二叉排序树第九组数据结构课程设计二叉排序树实现

    在实现二叉排序树的过程中,首先需要明确设计任务。根据描述,设计任务可能包括理解二叉排序树的概念,分析问题和需求,然后进行概要设计和详细设计。概要设计阶段,我们需要考虑如何存储二叉树的节点,以及设计用户...

    数据结构之二叉排序树的生成

    在压缩包文件“二叉排序树的相关操作”中,可能包含了实现这些功能的源代码,如C、C++或Java等编程语言的实现。通过阅读和分析这些代码,我们可以更深入地理解二叉排序树的内部机制,掌握数据结构和算法在实际编程中...

Global site tag (gtag.js) - Google Analytics