// Created by Frank M. Carrano and Tim Henry. // Copyright (c) 2013 __Pearson Education__. All rights reserved. // PARITALLY COMPLETE. /** @file BinaryTree.cpp */ #include "BinaryNodeTree.h" #include "BinaryNode.h" #include ////////////////////////////////////////////////////////////// // Protected Utility Methods Section ////////////////////////////////////////////////////////////// template int BinaryNodeTree::getHeightHelper(BinaryNode* subTreePtr) const { if (subTreePtr == nullptr) return 0; else return 1 + max(getHeightHelper(subTreePtr->getLeftChildPtr()), getHeightHelper(subTreePtr->getRightChildPtr())); } // end getHeightHelper template BinaryNode* BinaryNodeTree::balancedAdd(BinaryNode* subTreePtr, BinaryNode* newNodePtr) { if (subTreePtr == nullptr) return newNodePtr; else { BinaryNode* leftPtr = subTreePtr->getLeftChildPtr(); BinaryNode* rightPtr = subTreePtr->getRightChildPtr(); if (getHeightHelper(leftPtr) > getHeightHelper(rightPtr)) { rightPtr = balancedAdd(rightPtr , newNodePtr); subTreePtr->setRightChildPtr(rightPtr ); } else { leftPtr = balancedAdd(leftPtr, newNodePtr); subTreePtr->setLeftChildPtr(leftPtr); } // end if return subTreePtr; } // end if } // end balancedAdd template BinaryNode* BinaryNodeTree::copyTree(const BinaryNode* treePtr) const { BinaryNode* newTreePtr = nullptr; // Copy tree nodes during a preorder traversal if (treePtr != nullptr) { // Copy node newTreePtr = new BinaryNode(treePtr->getItem(), nullptr, nullptr); newTreePtr->setLeftChildPtr(copyTree(treePtr->getLeftChildPtr())); newTreePtr->setRightChildPtr(copyTree(treePtr->getRightChildPtr())); } // end if return newTreePtr; } // end copyTree template void BinaryNodeTree::destroyTree(BinaryNode* subTreePtr) { if (subTreePtr != nullptr) { destroyTree(subTreePtr->getLeftChildPtr()); destroyTree(subTreePtr->getRightChildPtr()); delete subTreePtr; } // end if } // end destroyTree ////////////////////////////////////////////////////////////// // Protected Tree Traversal Sub-Section ////////////////////////////////////////////////////////////// template void BinaryNodeTree::inorder(void visit(ItemType&), BinaryNode* treePtr) const { if (treePtr != nullptr) { inorder(visit, treePtr->getLeftChildPtr()); ItemType theItem = treePtr->getItem(); visit(theItem); inorder(visit, treePtr->getRightChildPtr()); } // end if } // end inorder ////////////////////////////////////////////////////////////// // PUBLIC METHODS BEGIN HERE ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Constructor and Destructor Section ////////////////////////////////////////////////////////////// template BinaryNodeTree::BinaryNodeTree() : rootPtr(nullptr) { } // end default constructor template BinaryNodeTree::BinaryNodeTree(const ItemType& rootItem) { rootPtr = new BinaryNode(rootItem, nullptr, nullptr); } // end constructor template BinaryNodeTree::BinaryNodeTree(const ItemType& rootItem, const BinaryNodeTree* leftTreePtr, const BinaryNodeTree* rightTreePtr) { rootPtr = new BinaryNode(rootItem, copyTree(leftTreePtr->rootPtr), copyTree(rightTreePtr->rootPtr)); } // end constructor template BinaryNodeTree::BinaryNodeTree(const BinaryNodeTree& treePtr) { rootPtr = copyTree(treePtr.rootPtr); } // end copy constructor template BinaryNodeTree::~BinaryNodeTree() { destroyTree(rootPtr); } // end destructor ////////////////////////////////////////////////////////////// // Public BinaryTreeInterface Methods Section ////////////////////////////////////////////////////////////// template bool BinaryNodeTree::add(const ItemType& newData) { BinaryNode* newNodePtr = new BinaryNode(newData); rootPtr = balancedAdd(rootPtr, newNodePtr); return true; } // end add } // end contains ////////////////////////////////////////////////////////////// // Public Traversals Section ////////////////////////////////////////////////////////////// template void BinaryNodeTree::inorderTraverse(void visit(ItemType&)) const { inorder(visit, rootPtr); } // end inorderTraverse