import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
class MyBSTDemo {
public static void main(String[] args) {
MyBST<Integer> myBST = new MyBST<>();
List<Integer> inOrder = new ArrayList<>();
inOrder.add(-8);
inOrder.add(-4);
inOrder.add(-2);
inOrder.add(-1);
inOrder.add(3);
inOrder.add(5);
inOrder.add(6);
inOrder.add(7);
inOrder.add(15);
inOrder.add(20);
List<Integer> preOrder = new ArrayList<>();
preOrder.add(5);
preOrder.add(-4);
preOrder.add(-8);
preOrder.add(-1);
preOrder.add(-2);
preOrder.add(3);
preOrder.add(15);
preOrder.add(6);
preOrder.add(7);
preOrder.add(20);
myBST.piBuildBST(preOrder, inOrder);
System.out.println(myBST.inOrder_Stack());
myBST.removeD(7);
myBST.addD(7);
System.out.println(myBST.inOrder_Stack());
}
}
public class MyBST<T extends Comparable<T>> {
private Node root;
private int size;
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0 || root == null;
}
public boolean add(T t) {
if (t == null) throw new IllegalArgumentException("param is null");
if (isEmpty()) {
root = new Node(t);
size++;
return true;
}
Node mid = root;
Node midPar = null;
int comp = 0;
while (mid != null) {
comp = t.compareTo(mid.value);
if (comp < 0) {
midPar = mid;
mid = mid.left;
} else if (comp > 0) {
midPar = mid;
mid = mid.right;
} else {
return false;
}
}
if (t.compareTo(midPar.value) < 0) {
midPar.left = new Node(t);
} else {
midPar.right = new Node(t);
}
size++;
return true;
}
public boolean addD(T t) {
if (t == null) throw new IllegalArgumentException("param is null");
int oldSize = size;
root = addD(root, t);
return size > oldSize;
}
private Node addD(Node root, T t) {
if (root == null) {
size++;
return new Node(t);
}
int comp = t.compareTo(root.value);
if (comp < 0) {
root.left = addD(root.left, t);
} else if (comp > 0) {
root.right = addD(root.right, t);
} else {
throw new RuntimeException("param is exist");
}
return root;
}
public boolean contains(T t) {
if (t == null) throw new IllegalArgumentException("param is null");
if (isEmpty()) return false;
Node mid = root;
while (mid != null) {
int com = t.compareTo(mid.value);
if (com < 0) {
mid = mid.left;
} else if (com > 0) {
mid = mid.right;
} else {
return true;
}
}
return false;
}
public boolean removeD(T t) {
if (t == null) throw new IllegalArgumentException("param is null");
if (isEmpty()) throw new RuntimeException("Tree is empty");
int oldSize = size;
root = removeD(root, t);
return size < oldSize;
}
private Node removeD(Node root, T t) {
if (root == null) {
return null;
}
int comp = t.compareTo(root.value);
if (comp < 0) {
root.left = removeD(root.left, t);
} else if (comp > 0) {
root.right = removeD(root.right, t);
} else {
if (root.left != null && root.right != null) {
Node min = root.right;
while (min.left != null) {
min = min.left;
}
root.value = min.value;
removeD(root, min.value);
} else {
Node child = root.left != null ? root.left : root.right;
size--;
return child;
}
}
return root;
}
public boolean remove(T t) {
if (t == null) throw new IllegalArgumentException("param is null");
if (isEmpty()) throw new RuntimeException("Tree is empty");
Node mid = root;
Node midPar = null;
while (mid != null) {
int com = t.compareTo(mid.value);
if (com < 0) {
midPar = mid;
mid = mid.left;
} else if (com > 0) {
midPar = mid;
mid = mid.right;
} else {
break;
}
}
if (mid == null) return false;
if (mid.left != null && mid.right != null) {
Node minPar = mid;
Node min = mid.right;
while (min.left != null) {
minPar = min;
min = min.left;
}
mid.value = min.value;
midPar = minPar;
mid = min;
}
Node child = mid.left != null ? mid.left : mid.right;
if (midPar == null) {
root = child;
size--;
return true;
}
if (midPar.left == mid) {
midPar.left = child;
size--;
} else {
midPar.right = child;
size--;
}
return true;
}
public List<T> preOrder_Stack() {
if (isEmpty()) throw new RuntimeException("Tree is empty");
List<T> list = new ArrayList<>();
Stack<Node> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
Node pop = stack.pop();
list.add(pop.value);
if (pop.right != null) stack.push(pop.right);
if (pop.left != null) stack.push(pop.left);
}
return list;
}
public List<T> inOrder_Stack() {
if (isEmpty()) throw new RuntimeException("Tree is empty");
List<T> list = new ArrayList<>();
Stack<Node> stack = new Stack<>();
Node mid = root;
while (!stack.isEmpty() || mid != null) {
while (mid != null) {
stack.push(mid);
mid = mid.left;
}
Node pop = stack.pop();
list.add(pop.value);
mid = pop.right;
}
return list;
}
public List<T> postOrder_Stack() {
if (isEmpty()) throw new RuntimeException("Tree is empty");
List<T> list = new ArrayList<>();
Stack<Node> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
Node pop = stack.pop();
list.add(0, pop.value);
if (pop.left != null) stack.push(pop.left);
if (pop.right != null) stack.push(pop.right);
}
return list;
}
public List<T> preOrder() {
List<T> list = new ArrayList<>();
preOrder(root, list);
return list;
}
private void preOrder(Node root, List<T> list) {
if (root == null) return;
list.add(root.value);
preOrder(root.left, list);
preOrder(root.right, list);
}
public List<T> inOrder() {
List<T> list = new ArrayList<>();
inOrder(root, list);
return list;
}
private void inOrder(Node root, List<T> list) {
if (root == null) return;
inOrder(root.left, list);
list.add(root.value);
inOrder(root.right, list);
}
public List<T> PostOrder() {
List<T> list = new ArrayList<>();
PostOrder(root, list);
return list;
}
private void PostOrder(Node root, List<T> list) {
if (root == null) return;
PostOrder(root.left, list);
PostOrder(root.right, list);
list.add(root.value);
}
public List<T> levelOrder() {
List<T> list = new ArrayList<>();
MyListQueen<Node> queen = new MyListQueen<>();
queen.offer(root);
while (!queen.isEmpty()) {
Node poll = queen.poll();
list.add(poll.value);
if (poll.left != null) queen.offer(poll.left);
if (poll.right != null) queen.offer(poll.right);
}
return list;
}
public void ipBuildBST(List<T> inOrder, List<T> postOrder) {
root = ipBuildRoot(inOrder, postOrder);
size = inOrder.size();
}
private Node ipBuildRoot(List<T> inOrder, List<T> postOrder) {
if (inOrder.size() == 0) return null;
if (inOrder.size() == 1) return new Node(postOrder.get(0));
T nodeValue = postOrder.get(postOrder.size() - 1);
int index = inOrder.indexOf(nodeValue);
List<T> leftInOrder = inOrder.subList(0, index);
List<T> leftPostOrder = postOrder.subList(0, index);
List<T> rightInOrder = inOrder.subList(index + 1, inOrder.size());
List<T> rightPostOrder = postOrder.subList(index, postOrder.size() - 1);
Node node = new Node(nodeValue);
node.left = ipBuildRoot(leftInOrder, leftPostOrder);
node.right = ipBuildRoot(rightInOrder, rightPostOrder);
return node;
}
public void piBuildBST(List<T> preOrder, List<T> inOrder) {
root = piBuildRoot(preOrder, inOrder);
size = inOrder.size();
}
private Node piBuildRoot(List<T> preOrder, List<T> inOrder) {
if (inOrder.size() == 0) return null;
if (inOrder.size() == 1) return new Node(preOrder.get(0));
T rootValue = preOrder.get(0);
int index = inOrder.indexOf(rootValue);
List<T> leftInOrder = inOrder.subList(0, index);
List<T> leftPreOrder = preOrder.subList(1, index + 1);
List<T> rightInOrder = inOrder.subList(index + 1, inOrder.size());
List<T> rightPreOrder = preOrder.subList(index + 1, preOrder.size());
Node node = new Node(rootValue);
node.left = piBuildRoot(leftPreOrder, leftInOrder);
node.right = piBuildRoot(rightPreOrder, rightInOrder);
return node;
}
private class Node {
private T value;
private Node left;
private Node right;
private Node(T value) {
this.value = value;
}
}
}