import java.util.Scanner;
class BinaryTree<T extends Comparable<? super T>> {
class Node<T> {
public Node<T> left;
public Node<T> right;
public T key;
Node(T newKey) {
this.left = this.right = null;
this.key = newKey;
}
}
private Node<T> root;
public BinaryTree() { root = null; }
private void insertSub(Node<T> parentNode, Node<T> workNode, T newKey) {
// not use while-loop
//System.out.println(parentNode + ":" + workNode + ":(" + newKey + ")");
if (parentNode == null && workNode == null) {
this.root = new Node<T>(newKey);
return;
}
if (workNode == null) {
if (newKey.compareTo(parentNode.key) < 0)
parentNode.left = new Node<T>(newKey);
else
parentNode.right = new Node<T>(newKey);
} else {
if (newKey.compareTo(workNode.key) < 0)
insertSub(workNode, workNode.left, newKey);
else
insertSub(workNode, workNode.right, newKey);
}
}
public void insert(T newKey) { insertSub(null, root, newKey); }
private boolean deleteSub(Node<T> parentNode, Node<T> workNode, T newKey) {
// not use while-loop
// System.out.println(parentNode + ":" + workNode + ":(" + newKey + ")");
if (workNode == null)
return false;
if (parentNode == null) {
assert workNode == this.root;
assert workNode != null;
if (newKey.compareTo(workNode.key) == 0) {
/* delete root */
if (workNode.left == null) {
this.root = workNode.right;
return true;
}
if (workNode.right == null) {
this.root = workNode.left;
return true;
}
/* the top node has 2 child nodes */
this.root = workNode.left; /* == this.root */
Node<T> p;
for (p = workNode.left; p.right != null; p = p.right)
;
p.right = workNode.right;
return true;
} else {
if (newKey.compareTo(workNode.key) < 0)
return deleteSub(workNode, workNode.left, newKey);
else
return deleteSub(workNode, workNode.right, newKey);
}
}
assert workNode != this.root;
if (newKey.compareTo(workNode.key) != 0) {
if (newKey.compareTo(workNode.key) < 0)
return deleteSub(workNode, workNode.left, newKey);
else
return deleteSub(workNode, workNode.right, newKey);
}
//------------------------------------------------------------
assert newKey.compareTo(workNode.key) == 0;
if (workNode.right == null) {
if (parentNode.left == workNode) {
parentNode.left = workNode.left;
} else {
assert parentNode.right == workNode;
parentNode.right = workNode.left;
}
} else if (workNode.left == null) {
assert workNode.right != null;
if (parentNode.left == workNode) {
parentNode.left = workNode.right;
} else {
assert parentNode.right == workNode;
parentNode.right = workNode.right;
}
} else {
/* the parent node has 2 child nodes */
if (parentNode.left == workNode)
parentNode.left = workNode.left;
else
parentNode.right = workNode.left;
Node<T> p;
for (p = workNode.left; p.right != null; p = p.right)
;
p.right = workNode.right;
}
return true;
}
public boolean delete(T newKey) { return deleteSub(null, root, newKey); }
private static int N = 3;
private void vomitTree(Node<T> parent, int c) {
if (parent == null)
return;
vomitTree(parent.left, c + N);
for (int i
= 0; i
< c
; i
++) System.
out.
print(' '); System.
out.
println(parent.
key); vomitTree(parent.right, c + N);
}
public void vomitTree() { vomitTree(root, 0); }
}
class Main {
public static void main
(String[] args
) { BinaryTree<Integer> tree = new BinaryTree<>();
Scanner sc
= new Scanner
(System.
in);
for (;;) {
int input = 0;
input = sc.nextInt();
if (input < 0) break;
tree.insert(input);
tree.vomitTree();
}
System.
out.
println("deleteing");
for (;;) {
int input = 0;
input = sc.nextInt();
if (input < 0) break;
if (tree.
delete(input
) == false) System.
out.
println("not found.");
tree.vomitTree();
}
}
}
/* end */