public class BinarySearchTree<T extends Comparable> {
private static class Entity<T extends Comparable> {
private T node = null;
private Entity<T> parent = null;
private Entity<T> left = null;
private Entity<T> right = null;
public T getNode() {
return node;
}
public void setNode(T node) {
this.node = node;
}
public Entity<T> getParent() {
return parent;
}
public void setParent(Entity<T> parent) {
this.parent = parent;
}
public Entity<T> getLeft() {
return left;
}
public void setLeft(Entity<T> left) {
this.left = left;
}
public Entity<T> getRight() {
return right;
}
public void setRight(Entity<T> right) {
this.right = right;
}
}
private Entity<T> head = null;
public void append(T node) {
Entity<T> entity = new Entity<T>();
entity.setNode(node);
if(head == null) {
head = entity;
} else {
Entity<T> pointer = head;
while(pointer != null) {
if(pointer.getNode().compareTo(entity.getNode()) > 0) {
if(pointer.getLeft() == null) {
pointer.setLeft(entity);
entity.setParent(pointer);
break;
}
pointer = pointer.getLeft();
} else{
if(pointer.getRight() == null) {
pointer.setRight(entity);
entity.setParent(pointer);
break;
}
pointer = pointer.getRight();
}
}
}
}
public boolean remove(T node) {
if(head == null) return false;
Entity<T> pointer = head;
while(pointer != null) {
if(pointer.getNode().compareTo(node) > 0) {
pointer = pointer.getLeft();
} else if(pointer.getNode().compareTo(node) < 0) {
pointer = pointer.getRight();
} else {
removeNode(pointer);
return true;
}
}
return false;
}
private void removeNode(Entity<T> pointer) {
Entity<T> cursor = pointer;
while(true) {
if(cursor.getLeft() != null) {
cursor = cursor.getLeft();
} else if (cursor.getRight() != null) {
cursor = cursor.getRight();
} else {
break;
}
}
Entity<T> parent = cursor.getParent();
if(parent.getNode().compareTo(cursor.getNode()) > 0) {
parent.setLeft(null);
} else {
parent.setRight(null);
}
cursor.setParent(null);
pointer.setNode(cursor.getNode());
rebuild(pointer);
}
private void rebuild(Entity<T> pointer) {
if(pointer != null) {
if(pointer.getLeft() != null) {
if(pointer.getNode().compareTo(pointer.getLeft().getNode()) < 0) {
T node = pointer.getNode();
pointer.setNode(pointer.getLeft().getNode());
pointer.getLeft().setNode(node);
}
}
if(pointer.getRight() != null) {
if(pointer.getNode().compareTo(pointer.getRight().getNode()) > 0) {
T node = pointer.getNode();
pointer.setNode(pointer.getRight().getNode());
pointer.getLeft().setNode(node);
}
}
if(pointer.getLeft() != null) {
rebuild(pointer.getLeft());
}
if(pointer.getRight() != null) {
rebuild(pointer.getRight());
}
}
}
public void print() {
treeWalk(head);
System.out.println();
}
private void treeWalk(Entity<T> entity) {
if(entity != null) {
treeWalk(entity.getLeft());
System.out.print(entity.getNode() + " ");
treeWalk(entity.getRight());
}
}
public T search(T node) {
T result = binarySearch(head, node);
return result;
}
public T search2(T node) {
Entity<T> top = head;
while(top != null) {
if(node.equals(top.getNode())) {
return top.getNode();
}
if(node.compareTo(top.getNode()) > 0) {
top = top.getRight();
} else {
top = top.getLeft();
}
}
return null;
}
public T maximun() {
Entity<T> top = head;
while(top.getRight() != null) {
top = top.getRight();
}
return top.getNode();
}
public T minimum() {
Entity<T> top = head;
while(top.getLeft() != null) {
top = top.getLeft();
}
return top.getNode();
}
private T binarySearch(Entity<T> top, T node) {
if(top == null) return null;
if(node.equals(top.getNode())) {
return top.getNode();
}
if(node.compareTo(top.getNode()) > 0) {
return binarySearch(top.getRight(), node);
} else {
return binarySearch(top.getLeft(), node);
}
}
public static void main(String[] args) {
BinarySearchTree<Integer> tree = new BinarySearchTree<Integer>();
tree.append(10);
tree.append(5);
tree.append(13);
tree.append(6);
tree.append(4);
tree.append(18);
tree.append(11);
tree.append(9);
tree.append(16);
tree.append(7);
tree.append(2);
tree.print();
tree.remove(5);
tree.remove(18);
tree.print();
System.out.println(tree.search(18));
}
}