package com.mybatis.test;
import java.nio.BufferUnderflowException;
/**
* @ClassName BinarySearchTree
* @Description
* @Author
* @Date 2019/10/19 0:01
* @Version 1.0
**/
public class BinarySearchTree<T extends Comparable<? super T>> {
//成员变量
private BinaryNode<T> root;
public BinarySearchTree(){
root = null;
}
public void makeEmpty(){
root = null;
}
public boolean isEmpty(){
return root == null;
}
public boolean contains(T x){
return contains(x,root);
}
public T findMin(){
if(isEmpty())
throw new BufferUnderflowException();
return findMin(root).element;
}
public T findMax(){
if(isEmpty())
throw new BufferUnderflowException();
return findMax(root).element;
}
//节点类
private static class BinaryNode<T>{
T element;
BinaryNode<T> left;
BinaryNode<T> right;
BinaryNode(T theElement,BinaryNode<T> lt,BinaryNode<T> rt){
element = theElement;
left = lt;
right = rt;
}
}
/**
* 私有方法
*/
//树中是否包含x节点
private boolean contains(T x,BinaryNode<T> t){
if(t == null)
return false;
int compareResult = x.compareTo(t.element);
if(compareResult < 0)
return contains(x,t.left);
else if(compareResult > 0)
return contains(x,t.right);
else
return true;
}
//插入节点
private BinaryNode<T> insert(T x,BinaryNode<T> t){
if(t == null)
return new BinaryNode<T>(x,null,null);
int comapareResult = x.compareTo(t.element);
if(comapareResult < 0)
t.left = insert(x,t.left);
else if(comapareResult > 0)
t.right = insert(x,t.right);
return t;
}
//删除
private BinaryNode<T> remove(T x,BinaryNode<T> t){
if(t == null)
return t;
int compareResult = x.compareTo(t.element);
if(compareResult < 0)
t.left = remove(x,t.left);
else if(compareResult > 0)
t.right = remove(x,t.right);
else if(t.left!=null&&t.right!=null){
t.element = findMin(t.right).element;
t.right = remove(t.element,t.right);
}else
t = (t.left!=null)?t.left:t.right;
return t;
}
//查找最小
private BinaryNode<T> findMin(BinaryNode<T> t){
if(t == null)
return null;
else if(t.left == null)
return t;
return findMin(t);
}
//查找到最大
private BinaryNode<T> findMax(BinaryNode<T> t){
if(t!=null)
while(t.right != null)
t = t.right;
return t;
}
}
1、节点类
- 这里是一个内部类。
private static class BinaryNode<T>{
T element;
BinaryNode<T> left;
BinaryNode<T> right;
BinaryNode(T theElement,BinaryNode<T> lt,BinaryNode<T> rt){
element = theElement;
left = lt;
right = rt;
}
}
其中值用T这样泛型来表示(建议测试的时候用Integer类型),其中element表示该节点的值,left和right分别表示左右孩子。构造函数,初始化节点。
2、成员变量和简单方法
- 这里面根节点是root,构造函数设置root为空,makeEmpty设置节点值是空,isEmpty判断当前root是否是空。
//成员变量
private BinaryNode<T> root;
public BinarySearchTree(){
root = null;
}
public void makeEmpty(){
root = null;
}
public boolean isEmpty(){
return root == null;
}
3、私有contains方法
private boolean contains(T x,BinaryNode<T> t){
if(t == null)
return false;
int compareResult = x.compareTo(t.element);
if(compareResult < 0)
return contains(x,t.left);
else if(compareResult > 0)
return contains(x,t.right);
else
return true;
}
- 判断x是否在这个t树内。
- 如果这个树是空,直接返回。
- 利用compareTo 这个方法,判断比较后的结果,如果小于零,该节点的值继续与左子树的值递归比较。如果大于零,该节点的值继续与右子树的值进行比较。如果有相同的就返回true。
4、私有insert方法
private BinaryNode<T> insert(T x,BinaryNode<T> t){
if(t == null)
return new BinaryNode<T>(x,null,null);
int comapareResult = x.compareTo(t.element);
if(comapareResult < 0)
t.left = insert(x,t.left);
else if(comapareResult > 0)
t.right = insert(x,t.right);
return t;
}
- 如果当前的树是空值,就直接新建一个节点,值为x。
- 如果树不是空值,那么与值相比较,如果小于零,说明需要插入到左子树,如果大于零则需要插入右子树。
- 最后一定会遇到一个t = null的情况,那么就创建节点,返回数据,这时t.left或者t.right会接收。插入完成。
5、私有remove方法
private BinaryNode<T> remove(T x,BinaryNode<T> t){
if(t == null)
return t;
int compareResult = x.compareTo(t.element);
if(compareResult < 0)
t.left = remove(x,t.left);
else if(compareResult > 0)
t.right = remove(x,t.right);
else if(t.left!=null&&t.right!=null){
//删除两个孩子
t.element = findMin(t.right).element;
t.right = remove(t.element,t.right);
}else
//删除一个孩子
t = (t.left!=null)?t.left:t.right;
return t;
}
- 删除这个有点复杂,这里一共分为三种情况:
- 1、如果删除的是叶子节点,直接删除
- 2、如果删除的节点t有一个孩子,那么直接将t = (t.left!=null)?t.left:t.right,即可将t = t.left或者t = t.right。
- 3、如果删除的节点t有两个孩子,那么将查找t的左子树的最小节点的值付给t的值,然后然后删除这个最小节点。
6、查找最大查找最小
//查找最小
private BinaryNode<T> findMin(BinaryNode<T> t){
if(t == null)
return null;
else if(t.left == null)
return t;
return findMin(t);
}
//查找到最大
private BinaryNode<T> findMax(BinaryNode<T> t){
if(t!=null)
while(t.right != null)
t = t.right;
return t;
}
- 这个也比较容易懂!!
7、剩余方法
public boolean contains(T x){
return contains(x,root);
}
public T findMin(){
if(isEmpty())
throw new BufferUnderflowException();
return findMin(root).element;
}
public T findMax(){
if(isEmpty())
throw new BufferUnderflowException();
return findMax(root).element;
}
- 最后都是调用方法了。