text cover

Data Abstraction and Problem Solving with C++

Walls and Mirrors

by Frank M. Carrano

Addison Wesley Logo

BinaryTree.cpp

Go to the documentation of this file.
00001 
00017 #include <cstddef>  // definition of NULL
00018 #include <new>      // for bad_alloc
00019 #include "BinaryTree.h"      // header file
00020 
00021 using namespace std;
00022 
00023 BinaryTree::BinaryTree() : root(NULL)
00024 {
00025 }  // end default constructor
00026 
00027 BinaryTree::BinaryTree(const TreeItemType& rootItem)
00028    throw(TreeException)
00029 {
00030    try
00031    {
00032       root = new TreeNode(rootItem, NULL, NULL);
00033    }
00034    catch (bad_alloc e)
00035    {  delete root;
00036       throw TreeException(
00037     "TreeException: constructor cannot allocate memory");
00038    }  // end try
00039 }  // end constructor
00040 
00041 BinaryTree::BinaryTree(const TreeItemType& rootItem,
00042                        BinaryTree& leftTree,
00043                        BinaryTree& rightTree)
00044    throw(TreeException)
00045 {
00046    try
00047    {
00048       root = new TreeNode(rootItem, NULL, NULL);
00049 
00050       attachLeftSubtree(leftTree);
00051       attachRightSubtree(rightTree);
00052    }
00053    catch (bad_alloc e)
00054    {  delete root;
00055       throw TreeException(
00056     "TreeException: constructor cannot allocate memory");
00057    }  // end try
00058 }  // end constructor
00059 
00060 BinaryTree::BinaryTree(const BinaryTree& tree)
00061    throw(TreeException)
00062 {
00063    try
00064    {
00065       copyTree(tree.root, root);
00066    }
00067    catch (bad_alloc e)
00068    {  destroyTree(tree.root);
00069       throw TreeException(
00070     "TreeException: copy constructor cannot allocate memory");
00071    }  // end try
00072 }  // end copy constructor
00073 
00074 BinaryTree::BinaryTree(TreeNode *nodePtr) : root(nodePtr)
00075 {
00076 }  // end protected constructor
00077 
00078 BinaryTree::~BinaryTree()
00079 {
00080    destroyTree(root);
00081 }  // end destructor
00082 
00083 bool BinaryTree::isEmpty() const
00084 {
00085    return (root == NULL);
00086 }  // end isEmpty
00087 
00088 TreeItemType BinaryTree::getRootData() const
00089    throw(TreeException)
00090 {
00091    if (isEmpty())
00092       throw TreeException("TreeException: Empty tree");
00093    return root->item;
00094 }  // end getRootData
00095 
00096 void BinaryTree::setRootData(const TreeItemType& newItem)
00097    throw(TreeException)
00098 {
00099    if (!isEmpty())
00100       root->item = newItem;
00101    else
00102    {
00103       try
00104       {
00105     root = new TreeNode(newItem, NULL, NULL);
00106       }
00107       catch (bad_alloc e)
00108       {
00109     throw TreeException(
00110        "TreeException: setRootData cannot allocate memory");
00111       }  // end try
00112     }  // end if
00113 }  // end setRootData
00114 
00115 void BinaryTree::attachLeft(const TreeItemType& newItem)
00116    throw(TreeException)
00117 {
00118    if (isEmpty())
00119       throw TreeException("TreeException: Empty tree");
00120    else if (root->leftChildPtr != NULL)
00121       throw TreeException(
00122     "TreeException: Cannot overwrite left subtree");
00123    else  // Assertion: nonempty tree; no left child
00124    {
00125       try
00126       {
00127     root->leftChildPtr = new TreeNode(newItem, NULL, NULL);
00128       }
00129       catch (bad_alloc e)
00130       {
00131     throw TreeException(
00132        "TreeException: attachLeft cannot allocate memory");
00133       }  // `end try
00134    }  // end if
00135 }  // end attachLeft
00136 
00137 void BinaryTree::attachRight(const TreeItemType& newItem)
00138    throw(TreeException)
00139 {
00140    if (isEmpty())
00141       throw TreeException("TreeException: Empty tree");
00142    else if (root->rightChildPtr != NULL)
00143       throw TreeException(
00144     "TreeException: Cannot overwrite right subtree");
00145    else  // Assertion: nonempty tree; no right child
00146    {
00147       try
00148       {
00149     root->rightChildPtr = new TreeNode(newItem, NULL, NULL);
00150       }
00151       catch (bad_alloc e)
00152       {
00153     throw TreeException(
00154        "TreeException: attachRight cannot allocate memory");
00155       }  // `end try
00156    }  // end if
00157 }  // end attachRight
00158 
00159 void BinaryTree::attachLeftSubtree(BinaryTree& leftTree)
00160    throw(TreeException)
00161 {
00162    if (isEmpty())
00163       throw TreeException("TreeException: Empty tree");
00164    else if (root->leftChildPtr != NULL)
00165       throw TreeException(
00166     "TreeException: Cannot overwrite left subtree");
00167    else  // Assertion: nonempty tree; no left child
00168    {  root->leftChildPtr = leftTree.root;
00169       leftTree.root = NULL;
00170    }  // end if
00171 }  // end attachLeftSubtree
00172 
00173 void BinaryTree::attachRightSubtree(BinaryTree& rightTree)
00174    throw(TreeException)
00175 {
00176    if (isEmpty())
00177       throw TreeException("TreeException: Empty tree");
00178    else if (root->rightChildPtr != NULL)
00179       throw TreeException(
00180     "TreeException: Cannot overwrite right subtree");
00181    else  // Assertion: nonempty tree; no right child
00182    {  root->rightChildPtr = rightTree.root;
00183       rightTree.root = NULL;
00184    }  // end if
00185 }  // end attachRightSubtree
00186 
00187 void BinaryTree::detachLeftSubtree(BinaryTree& leftTree)
00188    throw(TreeException)
00189 {
00190    if (isEmpty())
00191       throw TreeException("TreeException: Empty tree");
00192    else
00193    {  leftTree = BinaryTree(root->leftChildPtr);
00194       root->leftChildPtr = NULL;
00195    }  // end if
00196 }  // end detachLeftSubtree
00197 
00198 void BinaryTree::detachRightSubtree(BinaryTree& rightTree)
00199    throw(TreeException)
00200 {
00201    if (isEmpty())
00202       throw TreeException("TreeException: Empty tree");
00203    else
00204    {  rightTree = BinaryTree(root->rightChildPtr);
00205       root->rightChildPtr = NULL;
00206    }  // end if
00207 }  // end detachRightSubtree
00208 
00209 BinaryTree BinaryTree::getLeftSubtree() const
00210    throw(TreeException)
00211 {
00212    TreeNode *subTreePtr;
00213 
00214    if (isEmpty())
00215       return BinaryTree();
00216    else
00217    {  copyTree(root->leftChildPtr, subTreePtr);
00218       return BinaryTree(subTreePtr);
00219    }  // end if
00220 }  // end getLeftSubtree
00221 
00222 BinaryTree BinaryTree::getRightSubtree() const
00223    throw(TreeException)
00224 {
00225    TreeNode *subTreePtr;
00226 
00227    if (isEmpty())
00228       return BinaryTree();
00229    else
00230    {  copyTree(root->rightChildPtr, subTreePtr);
00231       return BinaryTree(subTreePtr);
00232    }  // end if
00233 }  // end getRightSubtree
00234 
00235 void BinaryTree::preorderTraverse(FunctionType visit)
00236 {
00237    preorder(root, visit);
00238 }  // end preorderTraverse
00239 
00240 void BinaryTree::inorderTraverse(FunctionType visit)
00241 {
00242    inorder(root, visit);
00243 }  // end inorderTraverse
00244 
00245 void BinaryTree::postorderTraverse(FunctionType visit)
00246 {
00247    postorder(root, visit);
00248 }  // end postorderTraverse
00249 
00250 BinaryTree& BinaryTree::operator=(const BinaryTree& rhs)
00251    throw(TreeException)
00252 {
00253    if (this != &rhs)
00254    {  destroyTree(root);  // deallocate left-hand side
00255       copyTree(rhs.root, root);  // copy right-hand side
00256    }  // end if
00257    return *this;
00258 }  // end operator=
00259 
00260 void BinaryTree::copyTree(TreeNode *treePtr,
00261                           TreeNode *& newTreePtr) const
00262    throw(TreeException)
00263 {
00264    // preorder traversal
00265    if (treePtr != NULL)
00266    {  // copy node
00267       try
00268       {
00269     newTreePtr = new TreeNode(treePtr->item, NULL, NULL);
00270     copyTree(treePtr->leftChildPtr, newTreePtr->leftChildPtr);
00271     copyTree(treePtr->rightChildPtr, newTreePtr->rightChildPtr);
00272       }
00273       catch (bad_alloc e)
00274       {
00275     throw TreeException(
00276        "TreeException: copyTree cannot allocate memory");
00277       }  // `end try
00278    }
00279    else
00280       newTreePtr = NULL;  // copy empty tree
00281 }  // end copyTree
00282 
00283 void BinaryTree::destroyTree(TreeNode *& treePtr)
00284 {
00285    // postorder traversal
00286    if (treePtr != NULL)
00287    {  destroyTree(treePtr->leftChildPtr);
00288       destroyTree(treePtr->rightChildPtr);
00289       delete treePtr;
00290       treePtr = NULL;
00291    }  // end if
00292 }  // end destroyTree
00293 
00294 TreeNode *BinaryTree::rootPtr() const
00295 {
00296    return root;
00297 }  // end rootPtr
00298 
00299 void BinaryTree::setRootPtr(TreeNode *newRoot)
00300 {
00301    root = newRoot;
00302 }  // end setRoot
00303 
00304 void BinaryTree::getChildPtrs(TreeNode *nodePtr,
00305                               TreeNode *& leftPtr,
00306                               TreeNode *& rightPtr) const
00307 {
00308    leftPtr = nodePtr->leftChildPtr;
00309    rightPtr = nodePtr->rightChildPtr;
00310 }  // end getChildPtrs
00311 
00312 void BinaryTree::setChildPtrs(TreeNode *nodePtr,
00313                               TreeNode *leftPtr,
00314                               TreeNode *rightPtr)
00315 {
00316    nodePtr->leftChildPtr = leftPtr;
00317    nodePtr->rightChildPtr = rightPtr;
00318 }  // end setChildPtrs
00319 
00320 void BinaryTree::preorder(TreeNode *treePtr,
00321                           FunctionType visit)
00322 {
00323    if (treePtr != NULL)
00324    {  visit(treePtr->item);
00325       preorder(treePtr->leftChildPtr, visit);
00326       preorder(treePtr->rightChildPtr, visit);
00327    }  // end if
00328 }  // end preorder
00329 
00330 void BinaryTree::inorder(TreeNode *treePtr,
00331                          FunctionType visit)
00332 {
00333    if (treePtr != NULL)
00334    {  inorder(treePtr->leftChildPtr, visit);
00335       visit(treePtr->item);
00336       inorder(treePtr->rightChildPtr, visit);
00337    }  // end if
00338 }  // end inorder
00339 
00340 void BinaryTree::postorder(TreeNode *treePtr,
00341                            FunctionType visit)
00342 {
00343    if (treePtr != NULL)
00344    {  postorder(treePtr->leftChildPtr, visit);
00345       postorder(treePtr->rightChildPtr, visit);
00346       visit(treePtr->item);
00347    } // end if
00348 }  // end postorder
00349 // End of implementation file.

Generated on Sun Aug 27 21:29:16 2006 for AWLogo by  doxygen 1.4.6