package com.mybatis.datasources.common.tree;
/**
* Created by guoyao on 2017/5/9.
*/
public class BinaryTree<T extends Object & Comparable<? super T>> {
Node<T> root;
int size;
public void midOrder() {
order(root);
}
public void order(Node<T> node) {
if (node != null) {
order(node.leftChild);
System.out.println(node.data);
order(node.rightChild);
}
}
/**
* 删除指定节点
* @param key
* @return
*/
public boolean deleteKey(T key) {
Node<T> current=root;
boolean isLeftChild = false ;
while (current.data != key) {
if (key.compareTo(current.data) < 0) {
current=current.leftChild;
isLeftChild =true ;
} else {
current=current.rightChild;
isLeftChild = false ;
}
if (current == null) {
return false;
}
}
Node<T> parent = current.parentNode ;
if (current == null) {
return false;
}
if (!isParent(current)) {
if (isLeftChild) {
parent.leftChild = null ;
}else {
parent.rightChild = null ;
}
current = null ;
}
if (hasLeftOnly(current)) {
if (isLeftChild) {
parent.leftChild = current.leftChild ;
}else {
parent.rightChild = current.leftChild ;
}
current.leftChild.parentNode = parent ;
return true;
}
if (hasRightOnly(current)) {
if (isLeftChild) {
parent.leftChild = current.rightChild ;
}else {
parent.rightChild = current.rightChild ;
}
current.rightChild.parentNode = parent ;
return true;
}
Node<T> replace = getReplace(current);
if(current == root){
root = replace ;
}else if (isLeftChild){
parent.leftChild = replace;
}else {
parent.rightChild = replace ;
}
replace.leftChild = current.leftChild ;
replace.parentNode = current.parentNode;
current.leftChild.parentNode = replace;
current =null;
return true;
}
/**
* 获取替换删除节点的下一个节点 中序后继
* @param delNode
* @return
*/
private Node<T> getReplace(Node<T> delNode) {
Node<T> repalceParent = delNode ;
Node<T> repalce = delNode ;
Node<T> current = delNode.rightChild ;
while (current != null) {
repalceParent = repalce ;
repalce = current ;
current = current.leftChild;
}
if (repalce != delNode.rightChild) {
repalceParent.leftChild = null;
repalce.rightChild = delNode.rightChild ;
}
repalce.parentNode = delNode.parentNode;
return repalce ;
}
/**
* 是否只有左子节点
* @param current
* @return
*/
public boolean hasLeftOnly(Node<T> current) {
if (current.leftChild != null && current.rightChild == null) {
return true ;
}
return false ;
}
/**
* 是否只有右子节点
* @param current
* @return
*/
public boolean hasRightOnly(Node<T> current) {
if (current.rightChild != null && current.leftChild == null ) {
return true ;
}
return false ;
}
/**
* 是否为树 false 叶子节点
* @param current
* @return
*/
public boolean isParent(Node<T> current) {
if (current.leftChild == null && current.rightChild == null) {
return false;
}
return true;
}
/**
* 根据key查询节点
*
* @param key
* @return
*/
public Node<T> findNode(T key) {
Node<T> current=root;
while (current.data != key) {
if (key.compareTo(current.data) < 0) {
current=current.leftChild;
} else {
current=current.rightChild;
}
if (current == null) {
return null;
}
}
return current;
}
/**
* 查询key 根据二叉树的特性,大于向右,小于向左。
*
* @param key
* @return
*/
public boolean containKey(T key) {
if (findNode(key) == null) {
return false;
}
return true;
}
/**
* 查找最大值 向右遍历直到为null;
*
* @return
*/
public T finMax() {
Node<T> current=root;
Node<T> max=null;
while (current != null) {
max=current;
current=current.rightChild;
}
return max.data;
}
/**
* 查找最小值 向左遍历直到为null;
*
* @return
*/
public T finMin() {
Node<T> current=root;
Node<T> min=null;
while (current != null) {
min=current;
current=current.leftChild;
}
return min.data;
}
/**
* 插入数据 大于根向右,小于根向左,以此同理,比较后插入
*
* @param t
*/
public void insert(T t) {
Node<T> newNode=new Node<>(t);
if (root == null) {
root=newNode;
size++;
} else {
Node<T> current=this.root;
Node<T> parent;
while (true) {
parent=current;
if (t.compareTo(current.data) >= 0) {
current=current.rightChild;
if (current == null) {
parent.rightChild=newNode;
newNode.parentNode = parent;
size++;
return;
}
} else {
current=current.leftChild;
if (current == null) {
parent.leftChild=newNode;
newNode.parentNode = parent;
size++;
return;
}
}
}
}
}
static class Node<T> {
T data;
Node<T> leftChild;
Node<T> rightChild;
Node<T> parentNode;
public Node(T t) {
this.data=t;
}
}
}