Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #ifndef BINARY_NODE_TREE_
- #define BINARY_NODE_TREE_
- #include <memory>
- #include "BinaryTreeInterface.h"
- #include "BinarySearchTree.h"
- #include "BinaryNode.h"
- #include "PrecondViolatedExcep.h"
- #include "NotFoundException.h"
- #include <algorithm>
- using namespace std;
- template<class ItemType>
- class BinaryNodeTree : public BinaryTreeInterface<ItemType>
- {
- protected:
- shared_ptr<BinaryNode<ItemType>> rootPtr;
- protected:
- int getHeightHelper(std::shared_ptr<BinaryNode<ItemType>> subTreePtr) const;
- int getNumberOfNodesHelper(std::shared_ptr<BinaryNode<ItemType>> subTreePtr) const;
- shared_ptr<BinaryNode<ItemType>> balancedAdd(shared_ptr<BinaryNode<ItemType>> subTreePtr, shared_ptr<BinaryNode<ItemType>> newNodePtr);
- shared_ptr<BinaryNode<ItemType>> moveValuesUpTree(shared_ptr<BinaryNode<ItemType>> subTreePtr);
- virtual std::shared_ptr<BinaryNode<ItemType>> removeValue(shared_ptr<BinaryNode<ItemType>> subTreePtr, const ItemType target, bool& success);
- shared_ptr<BinaryNode<ItemType>> findNode(shared_ptr<BinaryNode<ItemType>> treePtr, const ItemType& target, bool& success) const;
- shared_ptr<BinaryNode<ItemType>> copyTree(const shared_ptr<BinaryNode<ItemType>> oldTreeRootPtr) const;
- void destroyTree(std::shared_ptr<BinaryNode<ItemType>> subTreePtr);
- void preorder(void visit(ItemType&), shared_ptr<BinaryNode<ItemType>> treePtr) const;
- void inorder(void visit(ItemType&), shared_ptr<BinaryNode<ItemType>> treePtr) const;
- void postorder(void visit(ItemType&), shared_ptr<BinaryNode<ItemType>> treePtr) const;
- public:
- BinaryNodeTree();
- BinaryNodeTree(const ItemType& rootItem);
- BinaryNodeTree(const ItemType& rootItem,
- const shared_ptr<BinaryNodeTree<ItemType>> leftTreePtr,
- const shared_ptr<BinaryNodeTree<ItemType>> rightTreePtr);
- BinaryNodeTree(const BinaryNodeTree<ItemType>& tree);
- virtual ~BinaryNodeTree();
- bool isEmpty() const;
- int getHeight() const;
- int getNumberOfNodes() const;
- ItemType getRootData() const;
- void setRootData(const ItemType& newData);
- bool add(const ItemType& newData);
- bool remove(const ItemType& data);
- void clear();
- ItemType getEntry(const ItemType& anEntry) const;
- bool contains(const ItemType& anEntry) const;
- void preorderTraverse(void visit(ItemType&)) const;
- void inorderTraverse(void visit(ItemType&)) const;
- void postorderTraverse(void visit(ItemType&)) const;
- BinaryNodeTree& operator=(const BinaryNodeTree& rightHandSide);
- };
- //==================================================================================================================================//
- // CONSTRUCTORS & DESTRUCTORS //
- //==================================================================================================================================//
- template<class ItemType>
- BinaryNodeTree<ItemType>::BinaryNodeTree()
- { }
- template<class ItemType>
- BinaryNodeTree<ItemType>::BinaryNodeTree(const ItemType& rootItem)
- :rootPtr(std::make_shared<BinaryNode<ItemType>>(rootItem, nullptr, nullptr))
- { }
- template<class ItemType>
- BinaryNodeTree<ItemType>::BinaryNodeTree(const ItemType& rootItem, const std::shared_ptr<BinaryNodeTree<ItemType>> leftTreePtr, const std::shared_ptr<BinaryNodeTree<ItemType>> rightTreePtr)
- :rootPtr(std::make_shared<BinaryNode<ItemType>>(rootItem, copyTree(leftTreePtr->rootPtr), copyTree(rightTreePtr->rootPtr)))
- { }
- template<class ItemType>
- BinaryNodeTree<ItemType>::BinaryNodeTree(const BinaryNodeTree<ItemType>& treePtr)
- {
- rootPtr = copyTree(treePtr.rootPtr);
- }
- template<class ItemType>
- BinaryNodeTree<ItemType>::~BinaryNodeTree()
- {
- destroyTree(rootPtr);
- }
- //==================================================================================================================================//
- // IMPLEMENTATIONS BELOW //
- //==================================================================================================================================//
- template<class ItemType>
- int BinaryNodeTree<ItemType>::getHeightHelper(shared_ptr<BinaryNode<ItemType>> subTreePtr) const
- {
- if (subTreePtr == nullptr)
- return 0;
- else
- return 1 + std::max(getHeightHelper(subTreePtr->getLeftChildPtr()), getHeightHelper(subTreePtr->getRightChildPtr()));
- }
- template<class ItemType>
- int BinaryNodeTree<ItemType>::getNumberOfNodesHelper(shared_ptr<BinaryNode<ItemType>> subTreePtr) const
- {
- if (subTreePtr == nullptr)
- return 0;
- else
- return 1 + getNumberOfNodesHelper(subTreePtr->getLeftChildPtr()) + getNumberOfNodesHelper(subTreePtr->getRightChildPtr());
- }
- template<class ItemType>
- std::shared_ptr<BinaryNode<ItemType>> BinaryNodeTree<ItemType>::balancedAdd(shared_ptr<BinaryNode<ItemType>> subTreePtr, shared_ptr<BinaryNode<ItemType>> newNodePtr)
- {
- if (subTreePtr == nullptr)
- return newNodePtr;
- else
- {
- auto leftPtr = subTreePtr->getLeftChildPtr();
- auto rightPtr = subTreePtr->getRightChildPtr();
- if (getHeightHelper(leftPtr) > getHeightHelper(rightPtr))
- {
- rightPtr = balancedAdd(rightPtr , newNodePtr);
- subTreePtr->setRightChildPtr(rightPtr );
- }
- else
- {
- leftPtr = balancedAdd(leftPtr, newNodePtr);
- subTreePtr->setLeftChildPtr(leftPtr);
- }
- return subTreePtr;
- }
- }
- template<class ItemType>
- shared_ptr<BinaryNode<ItemType>> BinaryNodeTree<ItemType>::moveValuesUpTree(shared_ptr<BinaryNode<ItemType>> subTreePtr)
- {
- auto leftPtr = subTreePtr->getLeftChildPtr();
- auto rightPtr = subTreePtr->getRightChildPtr();
- int leftHeight = getHeightHelper(leftPtr);
- int rightHeight = getHeightHelper(rightPtr);
- if (leftHeight > rightHeight)
- {
- subTreePtr->setItem(leftPtr->getItem());
- leftPtr = moveValuesUpTree(leftPtr);
- subTreePtr->setLeftChildPtr(leftPtr);
- return subTreePtr;
- }
- else
- {
- if (rightPtr != nullptr)
- {
- subTreePtr->setItem(rightPtr->getItem());
- rightPtr =moveValuesUpTree(rightPtr);
- subTreePtr->setRightChildPtr(rightPtr);
- return subTreePtr;
- }
- else
- {
- return nullptr;
- }
- }
- }
- template<class ItemType>
- shared_ptr<BinaryNode<ItemType>> BinaryNodeTree<ItemType>::removeValue(shared_ptr<BinaryNode<ItemType>> subTreePtr, const ItemType target, bool& success)
- {
- if(subTreePtr == nullptr)
- return subTreePtr;
- if (subTreePtr->getItem() == target)
- {
- subTreePtr = moveValuesUpTree(subTreePtr);
- success = true;
- return subTreePtr;
- }
- else
- {
- auto targetNodePtr = removeValue(subTreePtr->getLeftChildPtr(), target, success);
- subTreePtr->setLeftChildPtr(targetNodePtr);
- if (!success)
- {
- targetNodePtr = removeValue(subTreePtr->getRightChildPtr(), target, success);
- subTreePtr->setRightChildPtr(targetNodePtr);
- }
- return subTreePtr;
- }
- }
- template<class ItemType>
- std::shared_ptr<BinaryNode<ItemType>> BinaryNodeTree<ItemType>::findNode(shared_ptr<BinaryNode<ItemType>> treePtr, const ItemType& target, bool& success) const
- {
- if (treePtr == nullptr)
- return treePtr;
- if (treePtr->getItem() == target)
- {
- success = true;
- return treePtr;
- }
- else
- {
- shared_ptr<BinaryNode<ItemType>> targetNodePtr = findNode(treePtr->getLeftChildPtr(), target, success);
- if (!success)
- {
- targetNodePtr = findNode(treePtr->getRightChildPtr(), target, success);
- }
- return targetNodePtr;
- }
- }
- template<class ItemType>
- shared_ptr<BinaryNode<ItemType>> BinaryNodeTree<ItemType>::copyTree(const shared_ptr<BinaryNode<ItemType>> oldTreeRootPtr) const
- {
- std::shared_ptr<BinaryNode<ItemType>> newTreePtr;
- if (oldTreeRootPtr != nullptr)
- {
- newTreePtr = make_shared<BinaryNode<ItemType>>(oldTreeRootPtr->getItem(), nullptr, nullptr);
- newTreePtr->setLeftChildPtr(copyTree(oldTreeRootPtr->getLeftChildPtr()));
- newTreePtr->setRightChildPtr(copyTree(oldTreeRootPtr->getRightChildPtr()));
- }
- return newTreePtr;
- }
- template<class ItemType>
- void BinaryNodeTree<ItemType>::destroyTree(shared_ptr<BinaryNode<ItemType>> subTreePtr)
- {
- if (subTreePtr != nullptr)
- {
- destroyTree(subTreePtr->getLeftChildPtr());
- destroyTree(subTreePtr->getRightChildPtr());
- subTreePtr.reset();
- }
- }
- template<class ItemType>
- void BinaryNodeTree<ItemType>::preorder(void visit(ItemType&), shared_ptr<BinaryNode<ItemType>> treePtr) const
- {
- if (treePtr != nullptr)
- {
- ItemType theItem = treePtr->getItem();
- visit(theItem);
- preorder(visit, treePtr->getLeftChildPtr());
- preorder(visit, treePtr->getRightChildPtr());
- }
- }
- template<class ItemType>
- void BinaryNodeTree<ItemType>::inorder(void visit(ItemType&), shared_ptr<BinaryNode<ItemType>> treePtr) const
- {
- if (treePtr != nullptr)
- {
- inorder(visit, treePtr->getLeftChildPtr());
- ItemType theItem = treePtr->getItem();
- visit(theItem);
- inorder(visit, treePtr->getRightChildPtr());
- }
- }
- template<class ItemType>
- void BinaryNodeTree<ItemType>::postorder(void visit(ItemType&), shared_ptr<BinaryNode<ItemType>> treePtr) const
- {
- if (treePtr != nullptr)
- {
- postorder(visit, treePtr->getLeftChildPtr());
- postorder(visit, treePtr->getRightChildPtr());
- ItemType theItem = treePtr->getItem();
- visit(theItem);
- }
- }
- template<class ItemType>
- bool BinaryNodeTree<ItemType>::isEmpty() const
- {
- return rootPtr == nullptr;
- }
- template<class ItemType>
- int BinaryNodeTree<ItemType>::getHeight() const
- {
- return getHeightHelper(rootPtr);
- }
- template<class ItemType>
- int BinaryNodeTree<ItemType>::getNumberOfNodes() const
- {
- return getNumberOfNodesHelper(rootPtr);
- }
- template<class ItemType>
- void BinaryNodeTree<ItemType>::clear()
- {
- destroyTree(rootPtr);
- rootPtr.reset();
- }
- template<class ItemType>
- ItemType BinaryNodeTree<ItemType>::getRootData() const
- {
- if (isEmpty())
- throw PrecondViolatedExcep("getRootData() called with empty tree.");
- return rootPtr->getItem();
- }
- template<class ItemType>
- void BinaryNodeTree<ItemType>::setRootData(const ItemType& newItem)
- {
- if (isEmpty())
- rootPtr = std::make_shared<BinaryNode<ItemType>>(newItem, nullptr, nullptr);
- else
- rootPtr->setItem(newItem);
- }
- template<class ItemType>
- bool BinaryNodeTree<ItemType>::add(const ItemType& newData)
- {
- auto newNodePtr = std::make_shared<BinaryNode<ItemType>>(newData);
- rootPtr = balancedAdd(rootPtr, newNodePtr);
- return true;
- }
- template<class ItemType>
- bool BinaryNodeTree<ItemType>::remove(const ItemType& target)
- {
- bool isSuccessful = false;
- rootPtr = removeValue(rootPtr, target, isSuccessful);
- return isSuccessful;
- }
- template<class ItemType>
- ItemType BinaryNodeTree<ItemType>::getEntry(const ItemType& anEntry) const
- {
- bool isSuccessful = false;
- auto binaryNodePtr = findNode(rootPtr, anEntry, isSuccessful);
- if (isSuccessful)
- return binaryNodePtr->getItem();
- else
- throw NotFoundException("Entry not found in tree!");
- }
- template<class ItemType>
- bool BinaryNodeTree<ItemType>:: contains(const ItemType& anEntry) const
- {
- bool isSuccessful = false;
- findNode(rootPtr, anEntry, isSuccessful);
- return isSuccessful;
- }
- template<class ItemType>
- void BinaryNodeTree<ItemType>::preorderTraverse(void visit(ItemType&)) const
- {
- preorder(visit, rootPtr);
- }
- template<class ItemType>
- void BinaryNodeTree<ItemType>::inorderTraverse(void visit(ItemType&)) const
- {
- inorder(visit, rootPtr);
- }
- template<class ItemType>
- void BinaryNodeTree<ItemType>::postorderTraverse(void visit(ItemType&)) const
- {
- postorder(visit, rootPtr);
- }
- template<class ItemType>
- BinaryNodeTree<ItemType>& BinaryNodeTree<ItemType>::operator=(
- const BinaryNodeTree<ItemType>& rightHandSide)
- {
- if (!isEmpty())
- clear();
- this = copyTree(&rightHandSide);
- return *this;
- }
- //==================================================================================================================================//
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement