diff --git a/src/tree/binarytree.hpp b/src/tree/binarytree.hpp index f6dbbca..f3dc268 100644 --- a/src/tree/binarytree.hpp +++ b/src/tree/binarytree.hpp @@ -11,9 +11,14 @@ struct Node std::unique_ptr> left; std::unique_ptr> right; + bool HasChildren() const + { + return static_cast(left) || static_cast(right); + } + bool IsLeaf() const { - return left == nullptr && right == nullptr; + return !HasChildren(); } Node(T const &_value) @@ -30,40 +35,52 @@ class Tree private: std::unique_ptr> root; - std::unique_ptr> & GetRightMostLeaf(std::unique_ptr> &node) + T ExtractSmallestLeaf(std::unique_ptr> &node) { - std::unique_ptr> *nodePtr = &node; - while ((*nodePtr)->right != nullptr) + std::unique_ptr> *nodePtr = &(node); + while ((*nodePtr)->HasChildren()) { - nodePtr = &((*nodePtr)->right); - } + if((*nodePtr)->left) + { + nodePtr = &((*nodePtr)->left); + } + else + { + T value = (*nodePtr)->value; + (*nodePtr) = std::move((*nodePtr)->right); + return value; + } + } - return *nodePtr; + T value = (*nodePtr)->value; + (*nodePtr).release(); + return value; } void DeleteNode(std::unique_ptr> & node) { - if(node || node->IsLeaf()) + if(!node || node->IsLeaf()) { node.release(); + return; } - if(node->left) + if(!(node->left)) { node = std::move(node->right); + return; } - if(node->right) + if(!(node->right)) { node = std::move(node->left); + return; } - auto & replacementNode = GetRightMostLeaf(node); - replacementNode->left.swap(node->left); - replacementNode->right.swap(node->right); - node.swap(replacementNode); + // In order successor - replacementNode.release(); + auto newNodeValue = ExtractSmallestLeaf(node->right); + node->value = newNodeValue; } std::unique_ptr> & FindNode(T const & value) @@ -80,7 +97,6 @@ private: currentPtr = &((*currentPtr)->right); } } - return *currentPtr; } @@ -121,10 +137,6 @@ public: void Delete(T const & value) { auto & node = FindNode(value); - if (node) - { - return; - } DeleteNode(node); }