package binaryTree; /** * 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. * * @author Alan L. Cox * @author Dung X. Nguyen - Copyright 1999 - All rights reserved. * @since 04/05/01 */ public class BiTree { /** * The state of this BiTree. */ private ANode _rootNode; /** * Initializes this BiTree to the empty state. */ public BiTree() { _rootNode = EmptyNode.Singleton; } /** * Get the data object at the root of this BiTree if it exists. * * @return the data object at the root of this BiTree if it exists. * @exception NoSuchElementException if this BiTree is empty. */ public Object getRootData() { return _rootNode.getRootData(); } /** * Set the data object at the root of this BiTree to the given data object. * * @param data the data object. * @exception NoSuchElementException if this BiTree is empty. */ public void setRootData(Object data) { _rootNode.setRootData(data); } /** * Get 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(); } /** * Attaches a new left subtree to the left of this BiTree, * allowing this BiTree to grow to the left. * * @param biTree the new left subtree. * @exception NoSuchElementException if this BiTree is empty. */ public void setLeftSubTree(BiTree biTree) { _rootNode.setLeftSubTree(biTree); } /** * 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(); } /** * Attaches a new right subtree to the right of this BiTree, * allowing this BiTree to grow to the right. * * @param biTree the new right subtree. * @exception NoSuchElementException if this BiTree is empty. */ public void setRightSubTree(BiTree biTree) { _rootNode.setRightSubTree(biTree); } /** * Changes an empty BiTree into a non-empty BiTree * with the given data at the root of the BiTree. * * @param data the data object. * @exception IllegalStateException if this BiTree is non-empty. */ public void insertRoot(Object data) { _rootNode.insertRoot(data, this); } /** * Removes and returns the data object at the root of this BiTree * if at least one of the subtrees is empty. The BiTree may * change from a non-empty to an empty state. * * @return the data object at the root of this BiTree. * @exception NoSuchElementException if this BiTree is empty. * @exception IllegalStateException if this BiTree has two * non-empty subtrees. */ public Object removeRoot() { return _rootNode.removeRoot(this); } /** * Hook to execute any algorithm that presents itself as a visitor * to this BiTree. * * @param algo a visitor to a BiTree. * @param input the input for the algo visitor. * @return the output for the execution of algo. */ public Object execute(IAlgo algo, Object input) { return _rootNode.execute(algo, input, this); } /** -- Package access only: -------------------------------------------- */ /** * Returns the current state of this BiTree. * * @return the current root node (i.e., state) of this BiTree. */ ANode getRootNode() { return _rootNode; } /** * Changes this BiTree to a given new state (i.e., node). * * @param node a new root node (i.e., state) for this BiTree. */ void setRootNode(ANode node) { _rootNode = node; } /** * Helper method for removeRoot(). * * @param sibling the sibbling of this BiTree. * @param parent the parent of this BiTree. * @return the data object at the parent of this BiTree. */ Object removeParent(BiTree sibling, BiTree parent) { return _rootNode.removeParent(sibling, parent, this); } /** * Helper method for removeParent(). * * @param sibling the sibbling of this BiTree. * @param parent the parent of this BiTree. * @return the root data of the parent of this BiTree. */ Object removeParentFromNonEmptyNode(BiTree sibling, BiTree parent) { return _rootNode.removeParentFromNonEmptyNode(sibling, parent); } }