From 1ef6e3eef40f2e58caf7f851792427afb729bcc7 Mon Sep 17 00:00:00 2001 From: Tuhin Mondal Date: Mon, 17 Jun 2024 17:40:19 -0700 Subject: [PATCH] Added BST implementation --- BinarySearchTree.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++ BinarySearchTree.h | 13 +++++----- BinaryTree.cpp | 55 +++++++++++++++++++++++++++++++++++++++ BinaryTree.h | 35 ++++++++++++++++++++----- BinaryTreeNode.h | 25 ++++++++++++++++++ 5 files changed, 177 insertions(+), 13 deletions(-) diff --git a/BinarySearchTree.cpp b/BinarySearchTree.cpp index 909c143..38542fe 100644 --- a/BinarySearchTree.cpp +++ b/BinarySearchTree.cpp @@ -1 +1,63 @@ #include "BinarySearchTree.h" + +template +void BinarySearchTree::insert(const T& newEntry) +{ + BinaryTreeNode* newNodePtr = new BinaryTreeNode(newEntry); + this->rootPtr = _insert(this->rootPtr, newNodePtr); + this->count++; +} + +template +BinaryTreeNode* BinarySearchTree::_insert(BinaryTreeNode* nodePtr, BinaryTreeNode* newNodePtr) { + BinaryTreeNode* pWalk = nodePtr, * parent = nullptr; + + if (!nodePtr) + { + nodePtr = newNodePtr; + return nodePtr; + } else { + while (pWalk) + { + parent = pWalk; + if (pWalk->getItem() > newNodePtr->getItem()) + pWalk = pWalk->getLeftPtr(); + else + pWalk = pWalk->getRightPtr(); + } + if (parent->getItem() > newNodePtr->getItem()) + parent->setLeftPtr(newNodePtr); + else + parent->setRightPtr(newNodePtr); + } + + return nodePtr; +} + +template +bool BinarySearchTree::search(const T& target, T& returnedItem) const +{ + BinarySearchTree* temp = nullptr; + + temp = _search(this->rootPtr, target); + if (temp) { + returnedItem = temp->getItem(); + return true; + } + + return false; +} + +template +BinaryTreeNode* BinarySearchTree::_search(BinaryTreeNode* nodePtr, const T& target) const +{ + BinaryTreeNode* found = nullptr; + + if (nodePtr) { + if (target.getCode() == nodePtr->getItem().getCode()) found = nodePtr; + else if (target.getCode() < nodePtr->getItem().getCode()) found = _search(nodePtr->getLeftPtr(), target); + else found = _search(nodePtr->getRightPtr(), target); + } + + return found; +} \ No newline at end of file diff --git a/BinarySearchTree.h b/BinarySearchTree.h index 378f4fd..db00249 100644 --- a/BinarySearchTree.h +++ b/BinarySearchTree.h @@ -6,17 +6,18 @@ template class BinarySearchTree: public BinaryTree { private: + BinaryTreeNode* _insert(BinaryTreeNode* nodePtr, BinaryTreeNode* newNode); + + BinaryTreeNode* _search(BinaryTreeNode* treePtr, const T& target) const; + + //BinaryNode* _remove(BinaryNode* nodePtr, const ItemType target, bool& success); public: - BinarySearchTree() : BinaryTree() {}; - - ~BinarySearchTree() { throw std::logic_error("Not implemented: ~BinarySearchTree()"); }; - - void insert(const T &item) { throw std::logic_error("Not implemented: BinarySearchTree.insert()"); }; + void insert(const T& item); void remove(const T &item) { throw std::logic_error("Not implemented: BinarySearchTree.remove()"); }; - BinaryTreeNode *search(const T &item) { return _search(this->root, item); }; + bool search(const T& target, T& returnedItem) const; }; #endif //INC_08_TEAM_PROJECT_BINARYSEARCHTREE_H diff --git a/BinaryTree.cpp b/BinaryTree.cpp index 1c97105..18df1c1 100644 --- a/BinaryTree.cpp +++ b/BinaryTree.cpp @@ -1 +1,56 @@ #include "BinaryTree.h" + +template +void BinaryTree::destroyTree(BinaryTreeNode* nodePtr) +{ + if (nodePtr) // != NULL + { + destroyTree(nodePtr->getLeftPtr()); + destroyTree(nodePtr->getRightPtr()); + delete nodePtr; + } +} + +template +void BinaryTree::_preorder(void visit(const T&), BinaryTreeNode* nodePtr) const +{ + if (nodePtr) { + T item = nodePtr->getItem(); + visit(item); + _preorder(visit, nodePtr->getLeftPtr()); + _preorder(visit, nodePtr->getRightPtr()); + } +} + +template +void BinaryTree::_inorder(void visit(const T&), BinaryTreeNode* nodePtr) const +{ + if (nodePtr) // != NULL + { + T item = nodePtr->getItem(); + _inorder(visit, nodePtr->getLeftPtr()); + visit(item); + _inorder(visit, nodePtr->getRightPtr()); + } +} + +template +void BinaryTree::_postorder(void visit(const T&), BinaryTreeNode* nodePtr) const +{ + if (nodePtr) { + T item = nodePtr->getItem(); + _postorder(visit, nodePtr->getLeftPtr()); + _postorder(visit, nodePtr->getRightPtr()); + visit(item); + } +} + +template +void BinaryTree::_printindented(void visit(const T&, int), BinaryTreeNode* nodePtr) const { + if (nodePtr) { + T item = nodePtr->getItem(); + _printInnerNodes(visit, nodePtr->getLeftPtr()); + if (nodePtr->getLeftPtr() || nodePtr->getRightPtr()) visit(item); + _printInnerNodes(visit, nodePtr->getRightPtr()); + } +} \ No newline at end of file diff --git a/BinaryTree.h b/BinaryTree.h index e8ffc75..1dbe773 100644 --- a/BinaryTree.h +++ b/BinaryTree.h @@ -5,28 +5,49 @@ template class BinaryTree { -private: +protected: BinaryTreeNode *root; int size; public: + BinaryTree() : root(nullptr), size(0) {}; - ~BinaryTree() { throw std::logic_error("Not implemented: ~BinaryTree()"); }; + BinaryTree(const BinaryTree& tree) { } + + ~BinaryTree() { destroyTree(root); }; [[nodiscard]] bool isEmpty() const { return size == 0; }; [[nodiscard]] int getSize() const { return size; }; - void clear() { throw std::logic_error("Not implemented: BinaryTree.clear()"); }; + void clear() { destroyTree(root); root = 0; size = 0; } - void preOrder(void visit(const T &)) { throw std::logic_error("Not implemented: BinaryTree.preOrder()"); }; + void preOrder(void visit(const T&)) const { _preorder(visit, root); } - void postOrder(void visit(const T &)) { throw std::logic_error("Not implemented: BinaryTree.postOrder()"); }; + void inOrder(void visit(const T&)) const { _inorder(visit, root); } - void inOrder(void visit(const T &)) { throw std::logic_error("Not implemented: BinaryTree.inOrder()"); }; + void postOrder(void visit(const T&)) const { _postorder(visit, root); } - void printIndented(void visit(const T &, int)) { throw std::logic_error("Not implemented: BinaryTree.printIndented()"); }; + void printIndented(void visit(const T&)) const { _printindented(visit, root, 0); } + + // abstract functions to be implemented by derived class + virtual void insert(const T& newData) = 0; + //virtual bool remove(const T &data) = 0; + virtual bool search(const T& target, T& returnedItem) const = 0; + +private: + // delete all nodes from the tree + void destroyTree(BinaryTreeNode* nodePtr); + + // internal traverse + void _preorder(void visit(const T&), BinaryTreeNode* nodePtr) const; + + void _inorder(void visit(const T&), BinaryTreeNode* nodePtr) const; + + void _postorder(void visit(const T&), BinaryTreeNode* nodePtr) const; + + void _printindented(void visit(const T&, int), BinaryTreeNode* nodePtr) const; }; diff --git a/BinaryTreeNode.h b/BinaryTreeNode.h index 6a5945c..2bc1e2b 100644 --- a/BinaryTreeNode.h +++ b/BinaryTreeNode.h @@ -5,6 +5,31 @@ template class BinaryTreeNode { +private: + T item; // Data portion + BinaryTreeNode* leftPtr; // Pointer to left child + BinaryTreeNode* rightPtr; // Pointer to right child + +public: + // constructors + BinaryTreeNode(const T& anItem) { item = anItem; leftPtr = 0; rightPtr = 0; } + BinaryTreeNode(const T& anItem, + BinaryTreeNode* left, + BinaryTreeNode* right) { + item = anItem; leftPtr = left; rightPtr = right; + } + // setters + void setItem(const T& anItem) { item = anItem; } + void setLeftPtr(BinaryTreeNode* left) { leftPtr = left; } + void setRightPtr(BinaryTreeNode* right) { rightPtr = right; } + + // getters + T getItem() const { return item; } + BinaryTreeNode* getLeftPtr() const { return leftPtr; } + BinaryTreeNode* getRightPtr() const { return rightPtr; } + + // other functions + bool isLeaf() const { return (leftPtr == 0 && rightPtr == 0); } };