Advertisement
Guest User

Untitled

a guest
Dec 5th, 2019
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.67 KB | None | 0 0
  1. #pragma once
  2.  
  3. #ifndef BINARY_NODE_TREE_
  4. #define BINARY_NODE_TREE_
  5.  
  6. #include <memory>
  7. #include "BinaryTreeInterface.h"
  8. #include "BinarySearchTree.h"
  9. #include "BinaryNode.h"
  10. #include "PrecondViolatedExcep.h"
  11. #include "NotFoundException.h"
  12. #include <algorithm>
  13.  
  14. using namespace std;
  15.  
  16. template<class ItemType>
  17. class BinaryNodeTree : public BinaryTreeInterface<ItemType>
  18. {
  19. protected:
  20.    shared_ptr<BinaryNode<ItemType>> rootPtr;
  21.    
  22. protected:
  23.    
  24.    int getHeightHelper(std::shared_ptr<BinaryNode<ItemType>> subTreePtr) const;
  25.    int getNumberOfNodesHelper(std::shared_ptr<BinaryNode<ItemType>> subTreePtr) const;
  26.    
  27.    shared_ptr<BinaryNode<ItemType>> balancedAdd(shared_ptr<BinaryNode<ItemType>> subTreePtr, shared_ptr<BinaryNode<ItemType>> newNodePtr);
  28.    
  29.    shared_ptr<BinaryNode<ItemType>> moveValuesUpTree(shared_ptr<BinaryNode<ItemType>> subTreePtr);
  30.  
  31.    virtual std::shared_ptr<BinaryNode<ItemType>> removeValue(shared_ptr<BinaryNode<ItemType>> subTreePtr,  const ItemType target, bool& success);
  32.    
  33.    shared_ptr<BinaryNode<ItemType>> findNode(shared_ptr<BinaryNode<ItemType>> treePtr, const ItemType& target, bool& success) const;
  34.    
  35.    shared_ptr<BinaryNode<ItemType>> copyTree(const shared_ptr<BinaryNode<ItemType>> oldTreeRootPtr) const;
  36.    
  37.    void destroyTree(std::shared_ptr<BinaryNode<ItemType>> subTreePtr);
  38.    
  39.    void preorder(void visit(ItemType&), shared_ptr<BinaryNode<ItemType>> treePtr) const;
  40.    void inorder(void visit(ItemType&), shared_ptr<BinaryNode<ItemType>> treePtr) const;
  41.    void postorder(void visit(ItemType&), shared_ptr<BinaryNode<ItemType>> treePtr) const;
  42.    
  43. public:
  44.    BinaryNodeTree();
  45.    BinaryNodeTree(const ItemType& rootItem);
  46.    BinaryNodeTree(const ItemType& rootItem,
  47.                    const shared_ptr<BinaryNodeTree<ItemType>> leftTreePtr,
  48.                    const shared_ptr<BinaryNodeTree<ItemType>> rightTreePtr);
  49.    BinaryNodeTree(const BinaryNodeTree<ItemType>& tree);
  50.    virtual ~BinaryNodeTree();
  51.  
  52.    bool isEmpty() const;
  53.    int getHeight() const;
  54.    int getNumberOfNodes() const;
  55.    ItemType getRootData() const;
  56.    void setRootData(const ItemType& newData);
  57.    bool add(const ItemType& newData);
  58.    bool remove(const ItemType& data);
  59.    void clear();
  60.    ItemType getEntry(const ItemType& anEntry) const;
  61.    bool contains(const ItemType& anEntry) const;
  62.    
  63.    void preorderTraverse(void visit(ItemType&)) const;
  64.    void inorderTraverse(void visit(ItemType&)) const;
  65.    void postorderTraverse(void visit(ItemType&)) const;
  66.    
  67.    BinaryNodeTree& operator=(const BinaryNodeTree& rightHandSide);
  68. };
  69.  
  70. //==================================================================================================================================//
  71. //                                                  CONSTRUCTORS & DESTRUCTORS                                                      //
  72. //==================================================================================================================================//
  73.  
  74. template<class ItemType>
  75. BinaryNodeTree<ItemType>::BinaryNodeTree()
  76. {  }
  77.  
  78. template<class ItemType>
  79. BinaryNodeTree<ItemType>::BinaryNodeTree(const ItemType& rootItem)
  80.                          :rootPtr(std::make_shared<BinaryNode<ItemType>>(rootItem, nullptr, nullptr))
  81. {  }
  82.  
  83. template<class ItemType>
  84. BinaryNodeTree<ItemType>::BinaryNodeTree(const ItemType& rootItem, const std::shared_ptr<BinaryNodeTree<ItemType>> leftTreePtr, const std::shared_ptr<BinaryNodeTree<ItemType>> rightTreePtr)
  85.                          :rootPtr(std::make_shared<BinaryNode<ItemType>>(rootItem, copyTree(leftTreePtr->rootPtr), copyTree(rightTreePtr->rootPtr)))
  86. {   }
  87.  
  88. template<class ItemType>
  89. BinaryNodeTree<ItemType>::BinaryNodeTree(const BinaryNodeTree<ItemType>& treePtr)
  90. {
  91.     rootPtr = copyTree(treePtr.rootPtr);
  92. }
  93.  
  94. template<class ItemType>
  95. BinaryNodeTree<ItemType>::~BinaryNodeTree()
  96. {
  97.     destroyTree(rootPtr);
  98. }
  99.  
  100. //==================================================================================================================================//
  101. //                                                   IMPLEMENTATIONS BELOW                                                          //
  102. //==================================================================================================================================//
  103.  
  104. template<class ItemType>
  105. int BinaryNodeTree<ItemType>::getHeightHelper(shared_ptr<BinaryNode<ItemType>> subTreePtr) const
  106. {
  107.     if (subTreePtr == nullptr)
  108.         return 0;
  109.     else
  110.         return 1 + std::max(getHeightHelper(subTreePtr->getLeftChildPtr()), getHeightHelper(subTreePtr->getRightChildPtr()));
  111. }
  112.  
  113. template<class ItemType>
  114. int BinaryNodeTree<ItemType>::getNumberOfNodesHelper(shared_ptr<BinaryNode<ItemType>> subTreePtr) const
  115. {
  116.     if (subTreePtr == nullptr)
  117.         return 0;
  118.     else
  119.         return 1 + getNumberOfNodesHelper(subTreePtr->getLeftChildPtr()) + getNumberOfNodesHelper(subTreePtr->getRightChildPtr());
  120. }
  121.  
  122. template<class ItemType>
  123. std::shared_ptr<BinaryNode<ItemType>> BinaryNodeTree<ItemType>::balancedAdd(shared_ptr<BinaryNode<ItemType>> subTreePtr, shared_ptr<BinaryNode<ItemType>> newNodePtr)
  124. {
  125.     if (subTreePtr == nullptr)
  126.         return newNodePtr;
  127.     else
  128.     {
  129.         auto leftPtr = subTreePtr->getLeftChildPtr();
  130.         auto rightPtr = subTreePtr->getRightChildPtr();
  131.        
  132.         if (getHeightHelper(leftPtr) > getHeightHelper(rightPtr))
  133.         {
  134.             rightPtr = balancedAdd(rightPtr , newNodePtr);
  135.             subTreePtr->setRightChildPtr(rightPtr );
  136.         }
  137.         else
  138.         {
  139.             leftPtr = balancedAdd(leftPtr, newNodePtr);
  140.             subTreePtr->setLeftChildPtr(leftPtr);
  141.         }  
  142.        
  143.         return subTreePtr;
  144.     }
  145. }
  146.  
  147. template<class ItemType>
  148. shared_ptr<BinaryNode<ItemType>> BinaryNodeTree<ItemType>::moveValuesUpTree(shared_ptr<BinaryNode<ItemType>> subTreePtr)
  149. {
  150.     auto  leftPtr = subTreePtr->getLeftChildPtr();
  151.     auto  rightPtr = subTreePtr->getRightChildPtr();
  152.     int leftHeight = getHeightHelper(leftPtr);
  153.     int rightHeight = getHeightHelper(rightPtr);
  154.     if (leftHeight > rightHeight)
  155.     {
  156.         subTreePtr->setItem(leftPtr->getItem());
  157.         leftPtr = moveValuesUpTree(leftPtr);
  158.         subTreePtr->setLeftChildPtr(leftPtr);
  159.         return subTreePtr;
  160.     }
  161.     else
  162.     {
  163.         if (rightPtr != nullptr)
  164.         {
  165.             subTreePtr->setItem(rightPtr->getItem());
  166.             rightPtr =moveValuesUpTree(rightPtr);
  167.             subTreePtr->setRightChildPtr(rightPtr);
  168.             return subTreePtr;
  169.         }
  170.         else
  171.         {
  172.             return nullptr;
  173.         }
  174.     }
  175. }  
  176.  
  177. template<class ItemType>
  178. shared_ptr<BinaryNode<ItemType>> BinaryNodeTree<ItemType>::removeValue(shared_ptr<BinaryNode<ItemType>> subTreePtr, const ItemType target, bool& success)
  179. {
  180.     if(subTreePtr == nullptr)
  181.         return subTreePtr;
  182.    
  183.     if (subTreePtr->getItem() == target)
  184.     {
  185.         subTreePtr = moveValuesUpTree(subTreePtr);
  186.         success = true;
  187.         return subTreePtr;
  188.     }
  189.     else
  190.     {
  191.         auto targetNodePtr = removeValue(subTreePtr->getLeftChildPtr(), target, success);
  192.         subTreePtr->setLeftChildPtr(targetNodePtr);
  193.         if (!success)
  194.         {
  195.             targetNodePtr = removeValue(subTreePtr->getRightChildPtr(), target, success);
  196.             subTreePtr->setRightChildPtr(targetNodePtr);
  197.         }  
  198.        
  199.         return subTreePtr;
  200.     }
  201. }
  202.  
  203. template<class ItemType>
  204. std::shared_ptr<BinaryNode<ItemType>> BinaryNodeTree<ItemType>::findNode(shared_ptr<BinaryNode<ItemType>> treePtr, const ItemType& target, bool& success) const
  205. {
  206.     if (treePtr == nullptr)
  207.         return treePtr;
  208.    
  209.     if (treePtr->getItem() == target)
  210.     {
  211.         success = true;
  212.         return treePtr;
  213.     }
  214.     else
  215.     {
  216.         shared_ptr<BinaryNode<ItemType>> targetNodePtr = findNode(treePtr->getLeftChildPtr(), target, success);
  217.         if (!success)
  218.         {
  219.             targetNodePtr = findNode(treePtr->getRightChildPtr(), target, success);
  220.         }  
  221.        
  222.         return targetNodePtr;
  223.     }  
  224. }  
  225.  
  226. template<class ItemType>
  227. shared_ptr<BinaryNode<ItemType>> BinaryNodeTree<ItemType>::copyTree(const shared_ptr<BinaryNode<ItemType>> oldTreeRootPtr) const
  228. {
  229.     std::shared_ptr<BinaryNode<ItemType>> newTreePtr;
  230.    
  231.     if (oldTreeRootPtr != nullptr)
  232.     {
  233.         newTreePtr = make_shared<BinaryNode<ItemType>>(oldTreeRootPtr->getItem(), nullptr, nullptr);
  234.         newTreePtr->setLeftChildPtr(copyTree(oldTreeRootPtr->getLeftChildPtr()));
  235.         newTreePtr->setRightChildPtr(copyTree(oldTreeRootPtr->getRightChildPtr()));
  236.     }
  237.    
  238.     return newTreePtr;
  239. }  
  240.  
  241. template<class ItemType>
  242. void BinaryNodeTree<ItemType>::destroyTree(shared_ptr<BinaryNode<ItemType>> subTreePtr)
  243. {
  244.     if (subTreePtr != nullptr)
  245.     {
  246.         destroyTree(subTreePtr->getLeftChildPtr());
  247.         destroyTree(subTreePtr->getRightChildPtr());
  248.         subTreePtr.reset();
  249.     }
  250. }  
  251.  
  252. template<class ItemType>
  253. void BinaryNodeTree<ItemType>::preorder(void visit(ItemType&), shared_ptr<BinaryNode<ItemType>> treePtr) const
  254. {
  255.     if (treePtr != nullptr)
  256.     {
  257.         ItemType theItem = treePtr->getItem();
  258.         visit(theItem);
  259.         preorder(visit, treePtr->getLeftChildPtr());
  260.         preorder(visit, treePtr->getRightChildPtr());
  261.     }
  262. }  
  263.  
  264. template<class ItemType>
  265. void BinaryNodeTree<ItemType>::inorder(void visit(ItemType&), shared_ptr<BinaryNode<ItemType>> treePtr) const
  266. {
  267.     if (treePtr != nullptr)
  268.     {
  269.         inorder(visit, treePtr->getLeftChildPtr());
  270.         ItemType theItem = treePtr->getItem();
  271.         visit(theItem);
  272.         inorder(visit, treePtr->getRightChildPtr());
  273.     }
  274. }  
  275.  
  276. template<class ItemType>
  277. void BinaryNodeTree<ItemType>::postorder(void visit(ItemType&), shared_ptr<BinaryNode<ItemType>> treePtr) const
  278. {
  279.     if (treePtr != nullptr)
  280.     {
  281.         postorder(visit, treePtr->getLeftChildPtr());
  282.         postorder(visit, treePtr->getRightChildPtr());
  283.         ItemType theItem = treePtr->getItem();
  284.         visit(theItem);
  285.     }
  286. }  
  287.  
  288. template<class ItemType>
  289. bool BinaryNodeTree<ItemType>::isEmpty() const
  290. {
  291.     return rootPtr == nullptr;
  292. }
  293.  
  294. template<class ItemType>
  295. int BinaryNodeTree<ItemType>::getHeight() const
  296. {
  297.     return getHeightHelper(rootPtr);
  298. }
  299.  
  300. template<class ItemType>
  301. int BinaryNodeTree<ItemType>::getNumberOfNodes() const
  302. {
  303.     return getNumberOfNodesHelper(rootPtr);
  304. }
  305.  
  306. template<class ItemType>
  307. void BinaryNodeTree<ItemType>::clear()
  308. {
  309.     destroyTree(rootPtr);
  310.     rootPtr.reset();
  311. }  
  312.  
  313. template<class ItemType>
  314. ItemType BinaryNodeTree<ItemType>::getRootData() const
  315. {
  316.     if (isEmpty())
  317.         throw PrecondViolatedExcep("getRootData() called with empty tree.");
  318.        
  319.         return rootPtr->getItem();
  320.         }
  321.  
  322. template<class ItemType>
  323. void BinaryNodeTree<ItemType>::setRootData(const ItemType& newItem)
  324. {
  325.     if (isEmpty())
  326.         rootPtr = std::make_shared<BinaryNode<ItemType>>(newItem, nullptr, nullptr);
  327.     else
  328.         rootPtr->setItem(newItem);
  329. }
  330.  
  331. template<class ItemType>
  332. bool BinaryNodeTree<ItemType>::add(const ItemType& newData)
  333. {
  334.     auto newNodePtr = std::make_shared<BinaryNode<ItemType>>(newData);
  335.     rootPtr = balancedAdd(rootPtr, newNodePtr);
  336.     return true;
  337. }
  338.  
  339. template<class ItemType>
  340. bool BinaryNodeTree<ItemType>::remove(const ItemType& target)
  341. {
  342.     bool isSuccessful = false;
  343.     rootPtr = removeValue(rootPtr, target, isSuccessful);
  344.     return isSuccessful;
  345. }
  346.  
  347. template<class ItemType>
  348. ItemType BinaryNodeTree<ItemType>::getEntry(const ItemType& anEntry) const
  349. {
  350.     bool isSuccessful = false;
  351.     auto binaryNodePtr = findNode(rootPtr, anEntry, isSuccessful);
  352.    
  353.     if (isSuccessful)
  354.         return binaryNodePtr->getItem();
  355.         else
  356.             throw NotFoundException("Entry not found in tree!");
  357.             }
  358.  
  359. template<class ItemType>
  360. bool BinaryNodeTree<ItemType>:: contains(const ItemType& anEntry) const
  361. {
  362.     bool isSuccessful = false;
  363.     findNode(rootPtr, anEntry, isSuccessful);
  364.     return isSuccessful;
  365. }
  366.  
  367. template<class ItemType>
  368. void BinaryNodeTree<ItemType>::preorderTraverse(void visit(ItemType&)) const
  369. {
  370.     preorder(visit, rootPtr);
  371. }
  372.  
  373. template<class ItemType>
  374. void BinaryNodeTree<ItemType>::inorderTraverse(void visit(ItemType&)) const
  375. {
  376.     inorder(visit, rootPtr);
  377. }
  378.  
  379. template<class ItemType>
  380. void BinaryNodeTree<ItemType>::postorderTraverse(void visit(ItemType&)) const
  381. {
  382.     postorder(visit, rootPtr);
  383. }  
  384.  
  385. template<class ItemType>
  386. BinaryNodeTree<ItemType>& BinaryNodeTree<ItemType>::operator=(
  387.                                                               const BinaryNodeTree<ItemType>& rightHandSide)
  388. {
  389.     if (!isEmpty())
  390.         clear();
  391.     this = copyTree(&rightHandSide);
  392.     return *this;
  393. }
  394.  
  395. //==================================================================================================================================//
  396.  
  397. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement