// Chap 10, pp 456 - 462
// Rename this file as BT.cpp

// ********************************************************
// 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(treeItemType NodeItem, ptrType L, ptrType R);
};  // end struct

treeNode::treeNode(treeItemType NodeItem, 
                   ptrType L, ptrType R):
   Item(NodeItem), LChildPtr(L), RChildPtr(R)
{
}  // end constructor

binTreeClass::binTreeClass() : Root(NULL)
{
}  // end default constructor

binTreeClass::binTreeClass(treeItemType RootItem)
{
   Root = new treeNode(RootItem, NULL, NULL);
   assert(Root != NULL);
}  // end constructor

binTreeClass::binTreeClass(ptrType NodePtr): 
   Root(NodePtr)
{
}  // end protected constructor

binTreeClass::binTreeClass(treeItemType RootItem, 
                           binTreeClass LeftTree, 
                           binTreeClass RightTree)
{
   boolean 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& T)
{
   CopyTree(T.Root, Root);
}  // end copy constructor

void binTreeClass::~binTreeClass()
{
   DestroyTree(Root);
}  // end destructor

boolean binTreeClass::BinaryTreeIsEmpty()
{
   return boolean(Root == NULL);
}  // end BinaryTreeIsEmpty

treeItemType binTreeClass::RootData()
{
   assert(Root != NULL);
   return Root->Item;
}  // end RootData

void binTreeClass::SetRootData(treeItemType NewItem)
{
   if (Root != NULL)
      Root->Item = NewItem;
   else
   {  Root = new treeNode(NewItem, NULL, NULL);
      assert(Root != NULL);
   }
}  // end SetRootData

void binTreeClass::AttachLeft(treeItemType NewItem, 
                              boolean& Success)
{
   Success = boolean(!BinaryTreeIsEmpty() &&
		     Root->LChildPtr == NULL);

   if (Success)
   {  // Assertion: nonempty tree and no left child
      Root->LChildPtr = new treeNode(NewItem, NULL, NULL);
      assert(Root->LChildPtr != NULL);
   }
 }  // end AttachLeft

void binTreeClass::AttachRight(treeItemType NewItem,
                               boolean& Success)
{
   Success = boolean(!BinaryTreeIsEmpty() &&
							Root->RChildPtr == NULL);

   if (Success)
   {  // Assertion: nonempty tree and no right child
      Root->RChildPtr = new treeNode(NewItem, NULL, NULL);
      assert(Root->RChildPtr != NULL);
   }
}  // end AttachRight

void binTreeClass::AttachLeftSubtree(binTreeClass LeftTree, 
                                     boolean& Success)
{
   Success = boolean(!BinaryTreeIsEmpty() &&
							Root->LChildPtr == NULL);

   if (Success)
      // Assertion: nonempty tree and no left child
      CopyTree(LeftTree.Root, Root->LChildPtr);
}  // end AttachLeftSubtree

void binTreeClass::AttachRightSubtree(binTreeClass RightTree, 
                                      boolean& Success)
{
   Success = boolean(!BinaryTreeIsEmpty() &&
		     Root->RChildPtr == NULL);

   if (Success)
      // Assertion: nonempty tree and no left child
      CopyTree(RightTree.Root, Root->RChildPtr);
}  // end AttachRightSubtree

void binTreeClass::DetachLeftSubtree(binTreeClass& LeftTree, 
                                     boolean& Success)
{
   Success = boolean(!BinaryTreeIsEmpty());
   if (Success)
   {  CopyTree(Root->LChildPtr, LeftTree.Root);
      DestroyTree(Root->LChildPtr);
   }
}  // end DetachLeftSubtree

void binTreeClass::DetachRightSubtree(binTreeClass& RightTree,
                                      boolean& Success)
{
   Success = boolean(!BinaryTreeIsEmpty());
   if (Success)
   {  CopyTree(Root->RChildPtr, RightTree.Root);
      DestroyTree(Root->RChildPtr);
   }
}  // end DetachRightSubtree

binTreeClass binTreeClass::LeftSubtree()
{
   ptrType SubTreePtr;

   if (BinaryTreeIsEmpty())
      return binTreeClass(NULL);
   else
   {  CopyTree(Root->LChildPtr, SubTreePtr);
      return binTreeClass(SubTreePtr);
   }
}  // end LeftSubtree

binTreeClass binTreeClass::RightSubtree()
{
   ptrType SubTreePtr;

   if (BinaryTreeIsEmpty())
      return binTreeClass(NULL);
   else
   {  CopyTree(Root->RChildPtr, SubTreePtr);
      return binTreeClass(SubTreePtr);
   }
}  // 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

void binTreeClass::operator=(const binTreeClass& T)
{
   CopyTree(T.Root, Root);
}  // end operator=

void binTreeClass::CopyTree(ptrType TreePtr, 
                            ptrType& NewTreePtr)
{
   // 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

void binTreeClass::SetRootPtr(ptrType NewRoot)
{
   Root = NewRoot;
}  // end SetRoot

ptrType binTreeClass::RootPtr()
{
   return Root;
}  // end RootPtr

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.

    Source: geocities.com/siliconvalley/program/2864/ds/CHAP10

               ( geocities.com/siliconvalley/program/2864/ds)                   ( geocities.com/siliconvalley/program/2864)                   ( geocities.com/siliconvalley/program)                   ( geocities.com/siliconvalley)