SOURCE FILE: BT.cpp
// ********************************************************
// Implementation file BT.cpp for the ADT binary tree.
// ********************************************************
#include "BT.h" // header file
#include <stddef.h> // definition of NULL
#include <assert.h> // 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.