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; } }