#include namespace BinaryTree { template struct Node { Node *parent; T value; std::unique_ptr> left; std::unique_ptr> right; bool IsLeaf() const { return left == nullptr && right == nullptr; } Node(T const &_value, Node *_parent) : parent(_parent), value(_value) { } }; template class Tree { private: std::unique_ptr> root; std::unique_ptr> & GetRightMostLeaf(std::unique_ptr> &localRoot) { std::unique_ptr> *nodePtr = &localRoot; while ((*nodePtr)->right != nullptr) { nodePtr = &((*nodePtr)->right); } return *nodePtr; } public: void Insert(T value) { Node *previousPtr = nullptr; std::unique_ptr> *rootPtr = &root; while (*rootPtr != nullptr) { previousPtr = rootPtr->get(); if ((*rootPtr)->value > value) { rootPtr = &((*rootPtr)->left); } else { rootPtr = &((*rootPtr)->right); } } *rootPtr = std::make_unique>(value, previousPtr); } bool Contains(T const value) { std::unique_ptr> *rootPtr = &root; while (*rootPtr != nullptr) { if ((*rootPtr)->value == value) { return true; } if ((*rootPtr)->value > value) { rootPtr = &((*rootPtr)->left); } else { rootPtr = &((*rootPtr)->right); } } return false; } void Delete(T const value) { std::unique_ptr> *rootPtr = &root; while (*rootPtr != nullptr) { if ((*rootPtr)->value == value) { if ((*rootPtr)->IsLeaf()) { rootPtr->release(); return; } if ((*rootPtr)->left == nullptr) { rootPtr->swap((*rootPtr)->right); (*rootPtr)->right.release(); } else if ((*rootPtr)->right == nullptr) { rootPtr->swap((*rootPtr)->left); (*rootPtr)->left.release(); } else { auto &replacementNode = GetRightMostLeaf((*rootPtr)->left); rootPtr->swap(replacementNode); replacementNode.release(); } return; } if ((*rootPtr)->value > value) { rootPtr = &((*rootPtr)->left); } else { rootPtr = &((*rootPtr)->right); } } } Tree() : root(nullptr) {} }; } // namespace BinaryTree