package brs;
/**
* Models the binary tree structure using the state pattern and the visitor
* pattern. Provides only structural behaviors and a hook to execute any
* visitor algorithm.
* Exercise: Override the toString() method anonymous inner visitor classes.
* @author Dung X. Nguyen - Copyright 2002 - All rights reserved.
*/
public class BiTree {
/**
* the state of this BiTree.
*/
private ANode _rootNode;
/**
* Initializes this BiTree to the empty state.
*/
public BiTree () {
_rootNode = EmptyNode.Singleton;
}
/**
* Gets the root data of this BiTree if it exists.
* @return the root data element of this BiTree if it exists.
* @exception NoSuchElementException if this BiTree is empty.
*/
public Object getRootDat() {
return _rootNode.getRootDat (this);
}
/**
* Sets the root data element to a given object.
* @param dat the new root data.
* @exception NoSuchElementException if this BiTree is empty.
*/
public void setRootDat(Object dat) {
_rootNode.setRootDat (dat, this);
}
/**
* Gets the left subtree of this BiTree if it exists.
* @return the left subtree of this BiTree if it exists.
* @exception NoSuchElementException if this BiTree is empty.
*/
public BiTree getLeftSubTree() {
return _rootNode.getLeftSubTree (this);
}
/**
* Gets the right subtree of this BiTree if it exsists.
* @return the right subtree of this BiTree if it exists.
* @exception NoSuchElementException if this BiTree is empty.
*/
public BiTree getRightSubTree() {
return _rootNode.getRightSubTree (this);
}
/**
* Attaches a new left subtree to the left of this BiTree, allowing this
* BiTree to grow to the left.
* @param biTree to replace the current left subtree.
* @exception NoSuchElementException if this BiTree is empty.
*/
public void setLeftSubTree(BiTree biTree) {
_rootNode.setLeftSubTree(biTree, this);
}
/**
* Attaches a new right subtree to the left of this BiTree, allowing this
* BiTree to grow to the right.
* @param biTree to replace the current right subtree.
* @exception NoSuchElementException if this BiTree is empty.
*/
public void setRightSubTree(BiTree biTree) {
_rootNode.setRightSubTree(biTree, this);
}
/**
* Inserts a root element to this BiTree.
* Allows for state change from empty to non-empty.
* @param dat the new root data.
* @exception IllegalStateException if this BiTree has more than one element.
*/
public void insertRoot(Object dat) {
_rootNode.insertRoot(dat, this);
}
/**
* Removes and returns the root data element of this BiTree.
* @return the root data element of this BiTree.
* @exception NoSuchElementException if this BiTree is empty.
* @exception IllegalStateException if one of the subtrees is not empty.
*/
public Object remRoot() {
return _rootNode.remRoot(this);
}
/**
* Hook to execute any algorithm that presents itself as a visitor to this
* BiTree.
* @param algo a visitor to a BiTree.
* @param inp the input for the algo visitor.
* @return the output for the execution of algo.
*/
public Object execute(IVisitor algo, Object inp) {
return _rootNode.execute(algo, inp, this);
}
public String toString () {
return (String)execute (ToString.Singleton, null);
// EXERCISE FOR STUDENTS: The above line of code does not conform to the
// state pattern because it does not forward the request to the state.
// Rewrite the code to conform to the state pattern. You will need to add
// appropriate methods to the states. Review what we did with toString()
// for linear recursive structures.
}
/**
* Changes this BiTree to a given new node (i.e. state).
* @param node a new root node (i.e.state) for this BiTree.
*/
final void setRootNode(ANode node) {
_rootNode = node;
}
/**
* Returns the current node (i.e. state) of this BiTree.
* @return the current root node (state) of this BiTree.
*/
final ANode getRootNode() {
return _rootNode;
}
}