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. Jquery来对form表单提交(mvc方案)

    来自:http://www.cnblogs.com/lmfeng/archive/2011/06/18/2084325.html 我先说明一下,这是asp.net mvc 里面的用法, Jquery来 ...

  2. 记录-java(jxl) Excel导入数据库

    本内容主要包括(文件上传.excel2003数据导入数据库)excel导入数据库功能需要jxl  jar包支持 下面是文件上传的前端测试代码 <%@ page language="ja ...

  3. AGS Server10.1中地图文档更新如何使服务更新

    一.需求背景 发布服务的mxd文档发生了更改,如何对该mxd文档映射的地图服务进行更新. 二.分析 由于在10.1中地图服务的发布采用的是msd的形式,也就是虽然在ArcMap中准备的地图文档是mxd ...

  4. vertical-align:middle;一般用于img和行内文字对齐方式

    vertical-align:top ;文字和行内块元素的顶部对齐 vertical-align:middle;居中 vertical-align:bottom;底对齐

  5. MySQL中myisam和innodb的主键索引有什么区别?

    MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址.下图是MyISAM索引的原理图: 这里设表一共有三列,假设我们以Col1为主键,则上图是一个MyISAM表的主索 ...

  6. RecyclerView添加分割线

    mRecyclerView = findView(R.id.id_recyclerview); //设置布局管理器 mRecyclerView.setLayoutManager(layout); // ...

  7. Matlab mser(最大极值稳定区域)

    在Matlab R2013a 和R2014a中已经实现MSER特征的提取. 一.函数detectMSERFeatures 输入的是M*N的灰度图片.可以指定阈值刻度,区域范围,感兴趣区域等参数. 输出 ...

  8. spring boot 2.0添加对fastjson的支持

    首先引入fastjson的maven依赖: <dependency> <groupId>com.alibaba</groupId> <artifactId&g ...

  9. 003 F-47创建预付定金请求检查增强-20150819.docx

    Enhancement SE38:LEINRF26   操作F-47,预付定金请求回车时,检查输入的采购订单项目发票视图,预付定金% 栏位,若为空,则报错,不为空可继续.   检查逻辑:检查采购凭证项 ...

  10. OSI参考模型与排错

    OSI参考模型中底层为其上层服务,因此排除网络故障应该也从底层到高层依次排查. 首先检查网络连接是否正常(物理层检查).例如网卡没有接好网线,将会看到带红叉的本地连接,属于物理层故障. 连接好网卡后, ...