135 lines
2.2 KiB
C++
135 lines
2.2 KiB
C++
#pragma once
|
|
#include <memory>
|
|
|
|
namespace BinaryTree
|
|
{
|
|
template <class T>
|
|
struct Node
|
|
{
|
|
T value;
|
|
|
|
std::unique_ptr<Node<T>> left;
|
|
std::unique_ptr<Node<T>> right;
|
|
|
|
bool IsLeaf() const
|
|
{
|
|
return left == nullptr && right == nullptr;
|
|
}
|
|
|
|
Node(T const &_value)
|
|
: value(_value),
|
|
left(nullptr),
|
|
right(nullptr)
|
|
{
|
|
}
|
|
};
|
|
|
|
template <class T>
|
|
class Tree
|
|
{
|
|
private:
|
|
std::unique_ptr<Node<T>> root;
|
|
|
|
std::unique_ptr<Node<T>> & GetRightMostLeaf(std::unique_ptr<Node<T>> &node)
|
|
{
|
|
std::unique_ptr<Node<T>> *nodePtr = &node;
|
|
while ((*nodePtr)->right != nullptr)
|
|
{
|
|
nodePtr = &((*nodePtr)->right);
|
|
}
|
|
|
|
return *nodePtr;
|
|
}
|
|
|
|
void DeleteNode(std::unique_ptr<Node<T>> & node)
|
|
{
|
|
if(node == nullptr || node->IsLeaf())
|
|
{
|
|
node.release();
|
|
}
|
|
|
|
if(node->left == nullptr)
|
|
{
|
|
node = std::move(node->right);
|
|
}
|
|
|
|
if(node->right == nullptr)
|
|
{
|
|
node = std::move(node->left);
|
|
}
|
|
|
|
auto & replacementNode = GetRightMostLeaf(node);
|
|
replacementNode->left.swap(node->left);
|
|
replacementNode->right.swap(node->right);
|
|
node.swap(replacementNode);
|
|
|
|
replacementNode.release();
|
|
}
|
|
|
|
std::unique_ptr<Node<T>> & FindNode(T const & value)
|
|
{
|
|
std::unique_ptr<Node<T>> *currentPtr = &root;
|
|
while (*currentPtr != nullptr && (*currentPtr)->value != value)
|
|
{
|
|
if ((*currentPtr)->value > value)
|
|
{
|
|
currentPtr = &((*currentPtr)->left);
|
|
}
|
|
else
|
|
{
|
|
currentPtr = &((*currentPtr)->right);
|
|
}
|
|
}
|
|
|
|
return *currentPtr;
|
|
}
|
|
|
|
public:
|
|
void Insert(T const & value)
|
|
{
|
|
std::unique_ptr<Node<T>> *currentPtr = &root;
|
|
while ((*currentPtr) != nullptr)
|
|
{
|
|
if ((*currentPtr)->value > value)
|
|
{
|
|
currentPtr = &((*currentPtr)->left);
|
|
}
|
|
else
|
|
{
|
|
currentPtr = &((*currentPtr)->right);
|
|
}
|
|
}
|
|
*currentPtr = std::make_unique<Node<T>>(value);
|
|
}
|
|
|
|
void InsertNoDuplicates(T const & value)
|
|
{
|
|
auto & toInsertIn = FindNode(value);
|
|
if(toInsertIn != nullptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
toInsertIn = std::make_unique<Node<T>>(value);
|
|
}
|
|
|
|
bool Contains(T const & value)
|
|
{
|
|
return FindNode(value) != nullptr;
|
|
}
|
|
|
|
void Delete(T const & value)
|
|
{
|
|
auto & node = FindNode(value);
|
|
if (node == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
DeleteNode(node);
|
|
}
|
|
|
|
Tree()
|
|
: root(nullptr)
|
|
{}
|
|
};
|
|
} // namespace BinaryTree
|