Created
April 12, 2015 21:56
-
-
Save iamOgunyinka/f2a15f31b4cfd57a5e1b to your computer and use it in GitHub Desktop.
BST
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef BST_CPP | |
#define BST_CPP | |
#include "BST.hpp" | |
template <class T> | |
void BST<T>::addElement(const T& value) | |
{ | |
addElement(value, root); | |
} | |
template <class T> | |
void BST<T>::addElement(const T& value, std::shared_ptr<Node> ¤tNode ) | |
{ | |
if( !currentNode ){ | |
currentNode = std::make_shared<Node>( value ); | |
} else { | |
auto currentNodePtr = currentNode; | |
while( true ){ | |
if( value <= currentNodePtr->getKey() ){ | |
if( currentNodePtr->getLeft() ){ | |
currentNodePtr = currentNodePtr->getLeft(); | |
} else { | |
currentNodePtr->setLeft( std::make_shared<Node>( value ) ); | |
currentNodePtr->getLeft()->setParent( currentNodePtr ); return; | |
} | |
} else { | |
if( currentNodePtr->getRight() ){ | |
currentNodePtr = currentNodePtr->getRight(); | |
} else { | |
currentNodePtr->setRight( std::make_shared<Node>( value ) ); | |
currentNodePtr->getRight()->setParent( currentNodePtr ); return; | |
} | |
} | |
} | |
} | |
} | |
template <class T> | |
void BST<T>::traverseBST(const std::shared_ptr<Node> ¤tR, std::ostream& out) | |
{ | |
if (currentR == nullptr) | |
return; | |
traverseBST(currentR->getLeft(), out); | |
out << currentR->getKey() << ' '; | |
traverseBST(currentR->getRight(), out); | |
} | |
template <class T> | |
std::shared_ptr<pNode<T>> BST<T>::findElement(const T& value, const std::shared_ptr<Node> & currentR) | |
{ | |
if (currentR == nullptr) | |
return currentR; | |
if (currentR->getKey() == value) | |
return currentR; | |
else if (currentR->getKey() < value) | |
return findElement(value, currentR->getRight()); //return currentR=keyNode | |
else | |
return findElement(value, currentR->getLeft()); | |
} | |
template <class T> | |
void BST<T>::removeElement(const T& value) | |
{ | |
auto keyNode = findElement(value, this->root); //find the node | |
removeElement(value, keyNode); | |
} | |
//this function is only called when there is a parent for sure | |
template <class T> | |
std::shared_ptr<pNode<T>> BST<T>::findParent(const T& value, | |
const std::shared_ptr<Node> & keyR, const std::shared_ptr<Node> & parentR) | |
{ | |
if (parentR == nullptr) | |
return parentR; | |
if (parentR->getLeft() == keyR || parentR->getRight() == keyR) | |
return parentR; | |
else if (parentR->getKey() < keyR->getKey()) | |
return findParent(value, keyR, parentR->getRight()); | |
else | |
return findParent(value, keyR, parentR->getLeft()); | |
} | |
template <class T> | |
void BST<T>::removeElement(const T& value, std::shared_ptr<Node> ¤tR) | |
{ | |
auto linking = [](std::shared_ptr<Node>& parentP, const std::shared_ptr<Node>& newNext, | |
const T& key) | |
{ (key > parentP->getKey()) ? parentP->setRight(newNext) : parentP->setLeft(newNext); }; | |
if (!currentR) | |
{ | |
std::cerr << "No such node\n"; | |
return; | |
} | |
else if (currentR->getLeft() == nullptr && currentR->getRight() == nullptr) //if leaf node | |
{ | |
auto parent = findParent(value, currentR, this->root); | |
if (parent == nullptr) root = nullptr; | |
else linking(parent, nullptr, currentR->getKey()); | |
currentR.reset(); | |
} | |
else if (currentR->getLeft() == nullptr) //if it has only right child | |
{ | |
if (currentR == this->root) | |
{ | |
this->root = currentR->getRight(); | |
currentR.reset(); | |
return; | |
} | |
auto parent = findParent(value, currentR, this->root); //find the parent of this node | |
linking(parent, currentR->getRight(), currentR->getKey()); | |
currentR.reset(); | |
} | |
else if (currentR->getRight() == nullptr) //if it has only left child | |
{ | |
if (currentR == this->root) | |
{ | |
this->root = currentR->getLeft(); | |
currentR.reset(); | |
return; | |
} | |
auto parent = findParent(value, currentR, this->root); | |
linking(parent, currentR->getLeft(), currentR->getKey()); | |
currentR.reset(); | |
} | |
else //most complicated case | |
{ | |
auto max = findMax(currentR->getLeft()); //find max in the left subtree | |
currentR->setKey(max->getKey()); | |
removeElement(max->getKey(), max); | |
} | |
} | |
template<class T> | |
std::shared_ptr<pNode<T>> BST<T>::findMax(std::shared_ptr<Node> root)//allow copying | |
{ | |
while (root->getRight() != nullptr) | |
{ | |
root = root->getRight(); | |
} | |
return root; | |
} | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef BST_H | |
#define BST_H | |
#include <memory> | |
#include <iostream> | |
template <class T> | |
class BST | |
{ | |
private: | |
class Node | |
{ | |
public: | |
Node() :Node(nullptr, nullptr, T{}) { } | |
Node(const T& val, const std::shared_ptr<Node>& Left = nullptr, | |
const std::shared_ptr<Node>& Right = nullptr) :pLeft{ Left }, pRight{ Right }, pParent{}, val{ val } { } | |
void setLeft(const std::shared_ptr<Node>&); | |
void setRight(const std::shared_ptr<Node>&); | |
void setParent( std::shared_ptr<Node> parent ); | |
std::shared_ptr<Node> getLeft() const { return pLeft; } | |
std::shared_ptr<Node> getRight() const { return pRight; } | |
std::shared_ptr<Node> getParent() const { return pParent; } | |
T getKey() const { return val; } | |
void setKey(const T& val); | |
private: | |
std::shared_ptr<Node> pLeft; | |
std::shared_ptr<Node> pRight; | |
std::shared_ptr<Node> pParent{}; | |
T val; | |
}; | |
std::shared_ptr<Node> root = nullptr; | |
static void traverseBST(const std::shared_ptr<Node> ¤tR, std::ostream& out); | |
static std::shared_ptr<Node> findElement(const T& value, const std::shared_ptr<Node> & currentR); | |
static std::shared_ptr<Node> findParent(const T& value, | |
const std::shared_ptr<Node> & keyR, const std::shared_ptr<Node> & parentR); | |
void addElement(const T& value, std::shared_ptr<Node> ¤tR); | |
void removeElement(const T& value, std::shared_ptr<Node> ¤tR); | |
public: | |
template <class U> | |
friend std::ostream& operator<< (std::ostream&, const BST<U>&); | |
std::shared_ptr<Node> findMax(std::shared_ptr<Node> root); | |
void addElement(const T& value); | |
void removeElement(const T& value); | |
}; | |
template <class T> | |
using pNode = typename BST<T>::Node; | |
template <class T> | |
inline void BST<T>::Node::setLeft(const std::shared_ptr<Node> &pLeft) | |
{ | |
this->pLeft = pLeft; | |
} | |
template <class T> | |
inline void BST<T>::Node::setRight(const std::shared_ptr<Node> &pRight) | |
{ | |
this->pRight = pRight; | |
} | |
template <class T> | |
inline void BST<T>::Node::setParent( std::shared_ptr<Node> parent ) | |
{ | |
pParent = parent; | |
} | |
template <class T> | |
inline void BST<T>::Node::setKey(const T& val) | |
{ | |
this->val = val; | |
} | |
template <class T> | |
inline std::ostream& operator<< (std::ostream& out, const BST<T>& tree) | |
{ | |
tree.traverseBST(tree.root, out); | |
out << std::endl; | |
return out; | |
} | |
#include "BST.cpp" | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment