abstract class Tree {
public abstract boolean contains((A, A) -> boolean less, A x);
public abstract Tree insert ((A, A) -> boolean less, A x);
}
class EmptyTree extends Tree {
public boolean contains((A, A) -> boolean less, A x) {
return false;
}
public Tree insert((A, A) -> boolean less, A x) {
return new Branch(x, this, this);
}
}
class Branch extends Tree {
A elem;
Tree left;
Tree right;
public Branch(A elem, Tree left, Tree right) {
this.elem = elem;
this.left = left;
this.right = right;
}
public boolean contains((A, A) -> boolean less, A x) {
if (less(x, elem))
return left.contains(less, x);
else if (less(elem, x))
return right.contains(less, x);
else // we assume total ordering, therefore x.equals(elem)
return true;
}
public Tree insert((A, A) -> boolean less, A x) {
if (less(x, elem))
return new Branch(elem, left.insert(less, x), right);
else if (less(elem, x))
return new Branch(elem, left, right.insert(less, x));
else
return this;
}
}
class StringBranch extends Branch {
StringBranch(String elem, Tree left, Tree right) {
super(elem, left, right);
}
private static boolean stringLess(String x, String y) {
return x.compareTo(y) > 0;
}
public boolean contains(String x) {
return contains(stringLess, x);
}
public Tree insert(String x) {
return insert(stringLess, x);
}
}