package com.test.tree;

import java.util.Iterator;

/**
* 编写TreeSet类的实现程序,其中相关的迭代器使用二叉查找树。
* 在每个节点上添加一个指向其父节点的链
* @author wyl
* @param <T>
*/
public class MyTreeSet<T extends Comparable<? super T>> { private BinaryNode<T> root; //根节点
int modCount = 0; //记录调整树结构的次数 public MyTreeSet(){
root = null;
}
/**
* 定义二叉查找树的节点
*/
private class BinaryNode<T>{
T data; //节点的值
BinaryNode<T> left; //节点的左节点
BinaryNode<T> right; //节点右节点
BinaryNode<T> parent; //节点的父节点 public BinaryNode(T data){
this(data, null, null, null);
} public BinaryNode(T data, BinaryNode<T> lt, BinaryNode<T> rt, BinaryNode<T> pt) {
this.data = data;
this.left = lt;
this.right = rt;
this.parent = pt;
}
} /**
* 定义TreeSet的迭代器
* @return
*/
public Iterator iterator(){
return new MyTreeSetIterator();
} private class MyTreeSetIterator implements Iterator { private BinaryNode<T> current = findMin(root);
private BinaryNode<T> previous;
private int expectedModCount = modCount;
private boolean okToRemove = false;
private boolean atEnd = false;
@Override
public boolean hasNext() {
// TODO Auto-generated method stub
return !atEnd;
} @Override
public T next() {
// TODO Auto-generated method stub
if(modCount != expectedModCount){
try {
throw new CurrentModificationException();
} catch (CurrentModificationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(!hasNext()){
try {
throw new NoSuchElementException();
} catch (NoSuchElementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} T nextItem = current.data;
previous = current;
if(current.right != null){
current = findMin(current.right);
}else{
BinaryNode<T> child = current;
current = current.parent;
while(current != null && current.left != child){
child = current;
current = current.parent;
}
if(current == null){
atEnd = true;
}
}
okToRemove = true;
return nextItem;
} @Override
public void remove(){
// TODO Auto-generated method stub
if(modCount != expectedModCount){
try {
throw new CurrentModificationException();
} catch (CurrentModificationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(!okToRemove){
throw new IllegalStateException();
} try {
MyTreeSet.this.remove(previous.data);
} catch (UnderflowException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
okToRemove = false;
}
} public void makeEmpty(){
modCount++ ;
root = null;
} public boolean isEmpty(){
return root == null;
}
public boolean contains(T x){
return contains(x, root);
} public boolean contains(T x, BinaryNode<T> t){
if(t == null){
return false;
}
int compareResult = x.compareTo(t.data);
if(compareResult < 0){
return contains(x, t.left);
}else if(compareResult > 0){
return contains(x, t.right);
}else{
return true;
}
} public T findMin(){
if(isEmpty()){
try {
throw new UnderflowException();
} catch (UnderflowException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return findMin(root).data;
} public T findMax(){
if(isEmpty()){
try {
throw new UnderflowException();
} catch (UnderflowException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return findMax(root).data;
} public void insert(T x){
root = insert(x, root, null);
} public void remove(T x) throws UnderflowException{
root = remove(x, root);
} public void printTree(){
if(isEmpty()){
System.out.println("Empty tree");
}else{
printTree(root);
}
} public void printTree(BinaryNode<T> t){
if(t != null){
printTree(t.left);
System.out.println(t.data);
printTree(t.right);
}
} public BinaryNode<T> remove(T x, BinaryNode<T> t){
if(t == null){
try {
throw new UnderflowException();
} catch (UnderflowException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
int compareResult = x.compareTo(t.data);
if(compareResult < 0){
t = remove(x, t.left);
}else if(compareResult > 0){
t = remove(x, t.right);
}else if(t.left != null && t.right != null){
//要删除的节点是含有左右子树的节点
t.data = findMin(t.right).data;//将右子树的最小值作为根节点
t.right = remove(t.data, t.right);
}else{
modCount++ ;
BinaryNode<T> oneChild;
oneChild = (t.left == null)?t.left:t.right;
oneChild.parent = t.parent;
t = oneChild;
}
return t;
} public BinaryNode<T> insert(T x, BinaryNode<T> t, BinaryNode<T> parent){
if(t == null){
modCount++ ;
//空树
return new BinaryNode(x, null, null, parent);
}
int compareResult = x.compareTo(t.data);
if(compareResult < 0){
//要插入的数小于节点值,插入到左子树
t.left = insert(x, t.left, t);
}else if(compareResult > 0){
//要插入的数小于节点值,插入到左子树
t.right = insert(x, t.right, t);
}else{ }
return t;
} public BinaryNode<T> findMin(BinaryNode<T> t){
// TODO Auto-generated method stub
if(t == null){
try {
throw new UnderflowException();
} catch (UnderflowException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else if(t.left == null){
return t;
}
return findMin(t.left);
} public BinaryNode<T> findMax(BinaryNode<T> t){
// TODO Auto-generated method stub
if(t == null){
try {
throw new UnderflowException();
} catch (UnderflowException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else if(t.right == null){
return t;
}
return findMax(t.right);
} public static void main(String[] args) {
MyTreeSet<Integer> myTreeSet = new MyTreeSet<Integer>();
myTreeSet.insert(24);
myTreeSet.insert(23);
myTreeSet.insert(16);
myTreeSet.insert(20);
myTreeSet.insert(28);
myTreeSet.insert(29);
System.out.println("最小值: "+ myTreeSet.findMin());
System.out.println("最大值: "+ myTreeSet.findMax());
Iterator iter = myTreeSet.iterator();
while(iter.hasNext()){
System.out.print(iter.next() + "、");
} }
}
class UnderflowException extends Exception{}
class CurrentModificationException extends Exception{}
class NoSuchElementException extends Exception{}

编写TreeSet类的实现程序,其中相关的迭代器使用二叉查找树的更多相关文章

  1. 35.按要求编写Java程序: (1)编写一个接口:InterfaceA,只含有一个方法int method(int n); (2)编写一个类:ClassA来实现接口InterfaceA,实现int method(int n)接口方 法时,要求计算1到n的和; (3)编写另一个类:ClassB来实现接口InterfaceA,实现int method(int n)接口 方法时,要求计算n的阶乘(n

      35.按要求编写Java程序: (1)编写一个接口:InterfaceA,只含有一个方法int method(int n): (2)编写一个类:ClassA来实现接口InterfaceA,实现in ...

  2. 程序员自己编写的类和JDK类是一种合作关系。

    封装类: JAVA为每一个简单数据类型提供了一个封装类,使每个简单数据类型可以被Object来装载. 除了int和char,其余类型首字母大写即成封装类. 转换字符的方式: int I=10; Str ...

  3. 程序员自己编写的类和JDK类是一种合作关系

    封装类: JAVA为每一个简单数据类型提供了一个封装类,使每个简单数据类型可以被Object来装载. 除了int和char,其余类型首字母大写即成封装类. 转换字符的方式: int I=10; Str ...

  4. 编写一个简单的C++程序

    编写一个简单的C++程序 每个C++程序都包含一个或多个函数(function),其中一个必须命名为main.操作系统通过调用main来运行C++程序.下面是一个非常简单的main函数,它什么也不干, ...

  5. Java API —— TreeSet类

    1.TreeSet类    1)TreeSet类概述         使用元素的自然顺序对元素进行排序         或者根据创建 set 时提供的 Comparator 进行排序          ...

  6. Swift互用性: 使用Objective-C特性编写Swift类(Swift 2.0版)-b

    本节包括内容: 继承Objective-C的类(Inheriting from Objective-C Classes) 采用协议(Adopting Protocols) 编写构造器和析构器(Writ ...

  7. SLAM+语音机器人DIY系列:(二)ROS入门——4.如何编写ROS的第一个程序hello_world

    摘要 ROS机器人操作系统在机器人应用领域很流行,依托代码开源和模块间协作等特性,给机器人开发者带来了很大的方便.我们的机器人“miiboo”中的大部分程序也采用ROS进行开发,所以本文就重点对ROS ...

  8. [渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序读取相关数据

    这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第七篇:为ASP.NET MVC应用程序 ...

  9. [渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序更新相关数据

    这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第八篇:为ASP.NET MVC应用程序 ...

随机推荐

  1. angularjs 发送ajax请求的问题

    在angularjs中使用 ajax 如果使用 jquery的 ajax发送请求会遇到结果返回了,但是页面的值却没有改变,如: $scope.queryNameMatch = function() { ...

  2. <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性

    <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性

  3. 简单echars说明和使用

    官方API:http://echarts.baidu.com/echarts2/doc/doc.htm 1.AMD规范的加载器——esl.js,这是什么? 答:关于AMD规范可以参考阮一峰的这篇文章 ...

  4. JQuery UI 入门

    1. JQuery UI 概述 1.1 JQuery UI 主要分为三部分: 交互部件(interactions):是一些与鼠标交互相关的内容; 小部件(widgets): 主要是一些页面的扩展; 效 ...

  5. pythpn的zip函数

    zip可接受多个序列作为参数,返回一个tuple列表. 例1:没有参数 >>> b = zip() >>> print b [] 例2:一个参数 >>& ...

  6. MySQL中Btree和Hash的局限小结

    在索引中,Btree索引和Hash索引的局限性,在这里粗略罗列一下 1 Btree局限 B-树中的节点都是顺序存储的,所以可以利用索引进行查找(找某些值),也可以对查询结果进行ORDER BY(注意O ...

  7. 六百字读懂 Git(转)

    add by zhj:还是原文 六百字读懂 Git 看着更舒服一些,显示更好 原文:六百字读懂 Git 英文原文:Git in 600 words 译注:来自 Hacker School 的 Mary ...

  8. Python 网络编程——socket

    一 客户端/服务器架构 客户端(Client)服务器(Server)架构,即C/S架构,包括 1.硬件C/S架构(打印机) 2.软件C/S架构(web服务) 理想/目标状态—— 最常用的软件服务器是 ...

  9. http请求设置setConnectTimeout()方法超时无响应

    相信非常多小伙伴在写 HttpURLConnection中都设置了setConnectTimeout()方法.目的就是在网络不好的情况下超时返回 然而我们设置的setConnectTimeout()并 ...

  10. Android:日常学习笔记(6)——探究活动(3)

    Android:日常学习笔记(6)——探究活动(3) 活动的生命周期 返回栈 Android中的活动是可以叠加的,我们每启动一个新活动,就会覆盖在原来的活动上,点击Back以后销毁最上面的活动,下面的 ...