package collections;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Stack;
public class BSTSet implements SortedTreeSet {
Node root;
private int size;
private int height;
private static class Node {
@SuppressWarnings("unchecked")
Comparable val;
Node left;
Node right;
Node parent;
@SuppressWarnings("unchecked")
public Node(Comparable val, Node left, Node right, Node parent) {
this.val = val;
this.left = left;
this.right = right;
this.parent = parent;
}
}
@SuppressWarnings("unchecked")
private static class BSTIterator implements Iterator {
private Stack par;
private BSTIterator(Node root) {
par = new Stack();
Node next = root;
while (next != null) {
par.push(next);
next = next.left;
}
}
public boolean hasNext() {
return !par.empty();
}
public Object next() {
if (par.empty()) {
throw new NoSuchElementException();
}
else {
Node cur = (Node) par.pop();
Node next = cur.right;
while (next != null) {
par.push(next);
next = next.left;
}
return cur.val;
}
}
public void remove() {
throw new UnsupportedOperationException();
}
}
public BSTSet() {
root = null;
}
@Override
public int height() {
return height;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("[");
traverseInOrder(root, sb);
sb.append("]");
return sb.toString();
}
private void traverseInOrder(Node t, StringBuffer sb) {
if (t != null) {
traverseInOrder(t.left, sb);
if (sb.length() > 1)
sb.append(", ");
sb.append(t.val);
traverseInOrder(t.right, sb);
}
}
@SuppressWarnings("unchecked")
@Override
public boolean add(Comparable key) {
Node x, current, parent;
parent = null;
current = root;
while (current != null) {
int cmpRes = key.compareTo(current.val);
if (cmpRes == 0)
return false;
parent = current;
if (cmpRes < 0)
current = current.left;
else
current = current.right;
}
x = new Node(key, null, null, parent);
size++;
if (parent != null) {
int cmpRes = key.compareTo(parent.val);
if (cmpRes < 0){
parent.left = x;
if(parent.right == null)
height++;
}
else{
parent.right = x;
if(parent.left == null)
height++;
}
} else{
root = x;
height++;
}
return true;
}
@Override
@SuppressWarnings("unchecked")
public boolean contains(Comparable key) {
Node current = root;
while (current != null) {
int cmpRes = key.compareTo(current.val);
if (cmpRes == 0)
return true;
if (cmpRes < 0)
current = current.left;
else
current = current.right;
}
return false;
}
@Override
public int getSize() {
return size;
}
@SuppressWarnings("unchecked")
@Override
public Iterator iterator() {
return new BSTIterator(root);
}
@SuppressWarnings("unchecked")
@Override
public boolean remove(Comparable key) {
Node x, y, z;
z = root;
while (z != null) {
int cmpRes = key.compareTo(z.val);
if (cmpRes == 0)
break;
else if (cmpRes < 0)
z = z.left;
else
z = z.right;
}
if (z == null)
return false;
if (z.left == null || z.right == null)
y = z;
else {
y = z.right;
while (y.left != null)
y = y.left;
}
if (y.left != null)
x = y.left;
else
x = y.right;
if (x != null)
x.parent = y.parent;
if (y.parent != null)
if (y == y.parent.left)
y.parent.left = x;
else
y.parent.right = x;
else
root = x;
if (y != z) {
y.left = z.left;
if (y.left != null)
y.left.parent = y;
y.right = z.right;
if (y.right != null)
y.right.parent = y;
y.parent = z.parent;
if (z.parent != null)
if (z == z.parent.left)
z.parent.left = y;
else
z.parent.right = y;
else
root = y;
}
size--;
return true;
}
}