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. Python 模块相对引用

    文件结构如下 python_directory/ ├── __init__.py └── app ├── __init__.py ├── sub1 │   ├── __init__.py │   └─ ...

  2. 学习编译并运行C代码

    以<UNIX网络编程>中的代码为例,学习如何编译并运行C代码. 根据 UNIX网络编程(第3版)环境搭建——使用MAC OSX10.10,能够成功运行 1.下载本书的头文件及示例源码原书地 ...

  3. html5 上传头像示例及其注意事项

    转自[B5教程网]:http://www.bcty365.com/content-142-5244-1.html 这次分享一个简易的上传头像示例,其大致流程为: 一.将选择的图片转为base64字符串 ...

  4. _utf8_encode _utf8_decode base64_encode base64_decode

    const Base64 = { // private property _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv ...

  5. 自定义admin

    平时我们用的django自带admin,怎么评价呢?一个字简陋,而且也人性化,如下图,首先只显示数据对象,如果要查看详细还有点进去,其次不能对自己想要的数据进行刷选 我们的期望是:数据如excel显示 ...

  6. rgba透明的兼容处理

    background-color: rgba(0, 0, 0, .6);filter: progid:DXImageTransform.Microsoft.gradient(startColorstr ...

  7. Servlet 运行原理

    一:servlet定义 Servlet是一个Java应用程序,运行在服务器端,用来处理客户端请求并作出响应的程序. 二:简单servlet实例 //导入所需的包 import javax.servle ...

  8. Dockerfile学习(一)

    FROM指令: 格式为:FROM<image>:<tag>或者FROM<image> Dockerfile的第一条指令必须是FROM,用来指定要制作的镜像继承自哪个 ...

  9. 剑指offer 面试23题

    面试23题: 题目:如果一个链表中包含环,如何找出环的入口节点? 解题分析:其实此题可以分解为三个题目:1)如何判断一个链表中是否包含环?2)如何找到环的入口节点?3)如何得到环中节点的数目? 解决此 ...

  10. tcpdump Demo

    tcpdump Demo lxw ~$ tcpdump -i eth0 tcpdump: eth0: You don't have permission to capture on that devi ...