// ******************************************************** // Implementation file BT.cpp for the ADT binary tree. // ******************************************************** #include "BT.h" // header file #include // definition of NULL #include // for assert() struct treeNode { treeItemType Item; ptrType LChildPtr, RChildPtr; // constructor: treeNode(const treeItemType& NodeItem, ptrType L, ptrType R); }; // end struct treeNode::treeNode(const treeItemType& NodeItem, ptrType L, ptrType R): Item(NodeItem), LChildPtr(L), RChildPtr(R) { } // end constructor binTreeClass::binTreeClass() : Root(NULL) { } // end default constructor binTreeClass::binTreeClass(const treeItemType& RootItem) { Root = new treeNode(RootItem, NULL, NULL); assert(Root != NULL); } // end constructor binTreeClass::binTreeClass(const treeItemType& RootItem, const binTreeClass& LeftTree, const binTreeClass& RightTree) { bool Success; Root = new treeNode(RootItem, NULL, NULL); assert(Root != NULL); AttachLeftSubtree(LeftTree, Success); if (Success) AttachRightSubtree(RightTree, Success); assert(Success); } // end constructor binTreeClass::binTreeClass(const binTreeClass& Tree) { CopyTree(Tree.Root, Root); } // end copy constructor binTreeClass::binTreeClass(ptrType NodePtr): Root(NodePtr) { } // end protected constructor binTreeClass::~binTreeClass() { DestroyTree(Root); } // end destructor bool binTreeClass::BinaryTreeIsEmpty() const { return bool(Root == NULL); } // end BinaryTreeIsEmpty treeItemType binTreeClass::RootData() const { assert(Root != NULL); return Root->Item; } // end RootData void binTreeClass::SetRootData(const treeItemType& NewItem) { if (Root != NULL) Root->Item = NewItem; else { Root = new treeNode(NewItem, NULL, NULL); assert(Root != NULL); } // end if } // end SetRootData void binTreeClass::AttachLeft(const treeItemType& NewItem, bool& Success) { Success = bool(!BinaryTreeIsEmpty() && Root->LChildPtr == NULL); if (Success) // Assertion: nonempty tree; no left child { Root->LChildPtr = new treeNode(NewItem, NULL, NULL); assert(Root->LChildPtr != NULL); } // end if } // end AttachLeft void binTreeClass::AttachRight(const treeItemType& NewItem, bool& Success) { Success = bool(!BinaryTreeIsEmpty() && Root->RChildPtr == NULL); if (Success) // Assertion: nonempty tree; no right child { Root->RChildPtr = new treeNode(NewItem, NULL, NULL); assert(Root->RChildPtr != NULL); } // end if } // end AttachRight void binTreeClass::AttachLeftSubtree(const binTreeClass& LeftTree, bool& Success) { Success = bool(!BinaryTreeIsEmpty() && Root->LChildPtr == NULL); if (Success) // Assertion: nonempty tree; no left child CopyTree(LeftTree.Root, Root->LChildPtr); } // end AttachLeftSubtree void binTreeClass::AttachRightSubtree(const binTreeClass& RightTree, bool& Success) { Success = bool(!BinaryTreeIsEmpty() && Root->RChildPtr == NULL); if (Success) // Assertion: nonempty tree; no right child CopyTree(RightTree.Root, Root->RChildPtr); } // end AttachRightSubtree void binTreeClass::DetachLeftSubtree(binTreeClass& LeftTree, bool& Success) { Success = bool(!BinaryTreeIsEmpty()); if (Success) { LeftTree = binTreeClass(Root->LChildPtr); Root->LChildPtr = NULL; } // end if } // end DetachLeftSubtree void binTreeClass::DetachRightSubtree(binTreeClass& RightTree, bool& Success) { Success = bool(!BinaryTreeIsEmpty()); if (Success) { RightTree = binTreeClass(Root->RChildPtr); Root->RChildPtr = NULL; } // end if } // end DetachRightSubtree binTreeClass binTreeClass::LeftSubtree() const { ptrType SubTreePtr; if (BinaryTreeIsEmpty()) return binTreeClass(); else { CopyTree(Root->LChildPtr, SubTreePtr); return binTreeClass(SubTreePtr); } // end if } // end LeftSubtree binTreeClass binTreeClass::RightSubtree() const { ptrType SubTreePtr; if (BinaryTreeIsEmpty()) return binTreeClass(); else { CopyTree(Root->RChildPtr, SubTreePtr); return binTreeClass(SubTreePtr); } // end if } // end RightSubtree void binTreeClass::PreorderTraverse(functionType Visit) { Preorder(Root, Visit); } // end PreorderTraverse void binTreeClass::InorderTraverse(functionType Visit) { Inorder(Root, Visit); } // end InorderTraverse void binTreeClass::PostorderTraverse(functionType Visit) { Postorder(Root, Visit); } // end PostorderTraverse binTreeClass& binTreeClass::operator=(const binTreeClass& Rhs) { if (this != &Rhs) { DestroyTree(Root); // deallocate left-hand side CopyTree(Rhs.Root, Root); // copy right-hand side } // end if return *this; } // end operator= void binTreeClass::CopyTree(ptrType TreePtr, ptrType& NewTreePtr) const { // preorder traversal if (TreePtr != NULL) { // copy node NewTreePtr = new treeNode(TreePtr->Item, NULL, NULL); assert(NewTreePtr != NULL); CopyTree(TreePtr->LChildPtr, NewTreePtr->LChildPtr); CopyTree(TreePtr->RChildPtr, NewTreePtr->RChildPtr); } // end if else NewTreePtr = NULL; // copy empty tree } // end CopyTree void binTreeClass::DestroyTree(ptrType& TreePtr) { // postorder traversal if (TreePtr != NULL) { DestroyTree(TreePtr->LChildPtr); DestroyTree(TreePtr->RChildPtr); delete TreePtr; TreePtr = NULL; } // end if } // end DestroyTree ptrType binTreeClass::RootPtr() const { return Root; } // end RootPtr void binTreeClass::SetRootPtr(ptrType NewRoot) { Root = NewRoot; } // end SetRoot void binTreeClass::GetChildPtrs(ptrType NodePtr, ptrType& LeftPtr, ptrType& RightPtr) const { LeftPtr = NodePtr->LChildPtr; RightPtr = NodePtr->RChildPtr; } // end GetChildPtrs void binTreeClass::SetChildPtrs(ptrType NodePtr, ptrType LeftPtr, ptrType RightPtr) { NodePtr->LChildPtr = LeftPtr; NodePtr->RChildPtr = RightPtr; } // end SetChildPtrs void binTreeClass::Preorder(ptrType TreePtr, functionType Visit) { if (TreePtr != NULL) { Visit(TreePtr->Item); Preorder(TreePtr->LChildPtr, Visit); Preorder(TreePtr->RChildPtr, Visit); } // end if } // end Preorder void binTreeClass::Inorder(ptrType TreePtr, functionType Visit) { if (TreePtr != NULL) { Inorder(TreePtr->LChildPtr, Visit); Visit(TreePtr->Item); Inorder(TreePtr->RChildPtr, Visit); } // end if } // end Inorder void binTreeClass::Postorder(ptrType TreePtr, functionType Visit) { if (TreePtr != NULL) { Postorder(TreePtr->LChildPtr, Visit); Postorder(TreePtr->RChildPtr, Visit); Visit(TreePtr->Item); } // end if } // end Postorder // End of implementation file.