/************************ IntBST.java **************************
* binary search tree of integers
*/
public class IntBST {
protected IntBSTNode root;
public IntBST() {
root = null;
}
public IntBSTNode search(int el) {
return search(root,el);
}
protected IntBSTNode search(IntBSTNode p, int el) {
while (p != null)
if (el == p.key)
return p;
else if (el < p.key)
p = p.left;
else p = p.right;
return null;
}
public void breadthFirst() {
IntBSTNode p = root;
Queue queue = new Queue();
if (p != null) {
queue.enqueue(p);
while (!queue.isEmpty()) {
p = (IntBSTNode) queue.dequeue();
p.visit();
if (p.left != null)
queue.enqueue(p.left);
if (p.right != null)
queue.enqueue(p.right);
}
}
}
public void preorder() {
preorder(root);
}
protected void preorder(IntBSTNode p) {
if (p != null) {
p.visit();
preorder(p.left);
preorder(p.right);
}
}
public void inorder() {
inorder(root);
}
protected void inorder(IntBSTNode p) {
if (p != null) {
inorder(p.left);
p.visit();
inorder(p.right);
}
}
public void postorder() {
postorder(root);
}
protected void postorder(IntBSTNode p) {
if (p != null) {
postorder(p.left);
postorder(p.right);
p.visit();
}
}
public void iterativePreorder() {
IntBSTNode p = root;
Stack travStack = new Stack();
if (p != null) {
travStack.push(p);
while (!travStack.isEmpty()) {
p = (IntBSTNode) travStack.pop();
p.visit();
if (p.right != null)
travStack.push(p.right);
if (p.left != null) // left child pushed after right
travStack.push(p.left);// to be on the top of the stack;
}
}
}
public void iterativeInorder() {
IntBSTNode p = root;
Stack travStack = new Stack();
while (p != null) {
while(p != null) { // stack the right child (if any)
if (p.right != null) // and the node itself when going
travStack.push(p.right); // to the left;
travStack.push(p);
p = p.left;
}
p = (IntBSTNode) travStack.pop(); // pop a node with no left child
while (!travStack.isEmpty() && p.right == null) { // visit it and all
p.visit(); // nodes with no right child;
p = (IntBSTNode) travStack.pop();
}
p.visit(); // visit also the first node with
if (!travStack.isEmpty()) // a right child (if any);
p = (IntBSTNode) travStack.pop();
else p = null;
}
}
public void iterativePostorder() {
IntBSTNode p = root;
Stack travStack = new Stack(), output = new Stack();
if (p != null) { // left-to-right postorder = right-to-left preorder
travStack.push(p);
while (!travStack.isEmpty()) {
p = (IntBSTNode) travStack.pop();
output.push(p);
if (p.left != null)
travStack.push(p.left);
if (p.right != null)
travStack.push(p.right);
}
while (!output.isEmpty()) {
p = (IntBSTNode) output.pop();
p.visit();
}
}
}
public void MorrisInorder() {
IntBSTNode p = root, tmp;
while (p != null)
if (p.left == null) {
p.visit();
p = p.right;
}
else {
tmp = p.left;
while (tmp.right != null && // go to the rightmost node of
tmp.right != p) // the left subtree or
tmp = tmp.right; // to the temporary parent of p;
if (tmp.right == null) {// if 'true' rightmost node was
tmp.right = p; // reached, make it a temporary
p = p.left; // parent of the current root,
}
else { // else a temporary parent has been
p.visit(); // found; visit node p and then cut
tmp.right = null; // the right pointer of the current
p = p.right; // parent, whereby it ceases to be
} // a parent;
}
}
public void insert(int el) {
IntBSTNode p = root, prev = null;
while (p != null) { // find a place for inserting new node;
prev = p;
if (p.key < el)
p = p.right;
else p = p.left;
}
if (root == null) // tree is empty;
root = new IntBSTNode(el);
else if (prev.key < el)
prev.right = new IntBSTNode(el);
else prev.left = new IntBSTNode(el);
}
public void deleteByCopying(int el) {
IntBSTNode node, p = root, prev = null;
while (p != null && p.key != el) { // find the node p
prev = p; // with element el;
if (p.key < el)
p = p.right;
else p = p.left;
}
node = p;
if (p != null && p.key == el) {
if (node.right == null) // node has no right child;
node = node.left;
else if (node.left == null) // no left child for node;
node = node.right;
else {
IntBSTNode tmp = node.left; // node has both children;
IntBSTNode previous = node; // 1.
while (tmp.right != null) { // 2. find the rightmost
previous = tmp; // position in the
tmp = tmp.right; // left subtree of node;
}
node.key = tmp.key; // 3. overwrite the reference
if (previous == node) // of the key being deleted;
previous.left = tmp.left; // 4.
else previous.right = tmp.left; // 5.
}
if (p == root)
root = node;
else if (prev.left == p)
prev.left = node;
else prev.right = node;
}
else if (root != null)
System.out.println("key " + el + " is not in the tree");
else System.out.println("the tree is empty");
}
public void deleteByMerging(int el) {
IntBSTNode tmp, node, p = root, prev = null;
while (p != null && p.key != el) { // find the node p
prev = p; // with element el;
if (p.key < el)
p = p.right;
else p = p.left;
}
node = p;
if (p != null && p.key == el) {
if (node.right == null) // node has no right child: its left
node = node.left; // child (if any) is attached to its parent;
else if (node.left == null) // node has no left child: its right
node = node.right; // child is attached to its parent;
else { // be ready for merging subtrees;
tmp = node.left; // 1. move left
while (tmp.right != null) // 2. and then right as far as
tmp = tmp.right; // possible;
tmp.right = // 3. establish the link between the
node.right; // the rightmost node of the left
// subtree and the right subtree;
node = node.left; // 4.
}
if (p == root)
root = node;
else if (prev.left == p)
prev.left = node;
else prev.right = node;
}
else if (root != null)
System.out.println("key " + el + " is not in the tree");
else System.out.println("the tree is empty");
}
public void balance(int data[], int first, int last) {
if (first <= last) {
int middle = (first + last)/2;
System.out.print(data[middle]+" ");
insert(data[middle]);
balance(data,first,middle-1);
balance(data,middle+1,last);
}
}
public void clear() {
root = null;
}
public boolean isEmpty() {
return root == null;
}
public boolean isInTree(int el) {
return search(root,el) != null;
}
}