#include <iostream>
#include <memory>
#include <stack>
#include <initializer_list>
template <typename T>
class Node
{
public:
Node(T *a) :p(NULL), left(NULL), right(NULL)
{
data.reset(a);
}
Node(Node &) = delete;
Node &operator = (Node &) = delete;
~Node() { }
bool operator != (const T &a)
{
return (*data != a);
}
bool operator < (const T &a)
{
return (*data < a);
}
Node *p;
Node *left;
Node *right;
std::shared_ptr<T> data;
};
//Binary Search Tree
template <typename T>
class BST
{
public:
BST() :root(NULL) { }
BST(std::initializer_list<T> l) :root(NULL)
{
auto beg = l.begin();
while (beg != l.end())
{
auto a = new T(*beg);
TreeInsert(a);
++beg;
}
}
~BST()
{
DeleteWholeTree();
}
Node<T> *Predecessor(Node<T> *)const;
Node<T> *Successor(Node<T> *)const;
bool TreeInsert(T *);
bool TreeDelete(const T &);
std::weak_ptr<T> TreeSearch(const T &)const;
void InorderTreeWalk()const;
private:
void DeleteWholeTree();
Node<T> *root;
};
template <typename T>
inline Node<T> *Maximum(Node<T> *a)
{
while (a->right != NULL)
{
a = a->right;
}
return a;
}
template <typename T>
inline Node<T> *BST<T>::Predecessor(Node<T> *a)const
{
if (a->left != NULL)
return Maximum(a->left);
auto temp = a->p;
while (temp != NULL&&temp->right != a)
{
a = temp;
temp = temp->p;
}
return temp;
}
template <typename T>
inline Node<T> *Minimum(Node<T> *a)
{
while (a->left != NULL)
{
a = a->left;
}
return a;
}
template <typename T>
inline Node<T> *BST<T>::Successor(Node<T> *)const
{
if (a->right != NULL)
return Minimum(a->right);
auto temp = a->p;
while (temp != NULL&&temp->left != a)
{
a = temp;
temp = temp->p;
}
return temp;
}
template <typename T>
inline bool BST<T>::TreeInsert(T *a)
{
//Data must be unique
if (auto temp = TreeSearch(*a).lock())
{
std::cout << "data " << *temp
<< " already exists" << std::endl;
return false;
}
auto x = root;
decltype(x) y = NULL;
while (x != NULL)
{
y = x;
if (*x < *a)
x = x->right;
else
x = x->left;
}
//Build a new Node
auto newNODE = new Node<T>(a);
newNODE->p = y;
if (y == NULL)
root = newNODE;
else if (*y < *a)
y->right = newNODE;
else
y->left = newNODE;
return true;
}
template <typename T>
inline std::weak_ptr<T>
BST<T>::TreeSearch(const T &k)const
{
auto temp = root;
while (temp != NULL&&*temp != k)
{
if (*temp < k)
temp = temp->right;
else
temp = temp->left;
}
if (temp == NULL)
return std::weak_ptr<T>();
else
return std::weak_ptr<T>(temp->data);
}
// Substitute Second for First
template <typename T>
inline void TransplantChildTree(T *&root, T *first, T *second)
{
if (first->p == NULL)
root = second;
else
(first->p->left == first) ?
(first->p->left = second) :
(first->p->right = second);
if (second != NULL)
second->p = first->p;
}
template <typename T>
inline bool BST<T>::TreeDelete(const T &k)
{
auto a = root;
while (a != NULL&&*a != k)
{
if (*a < k)
a = a->right;
else
a = a->left;
}
if (a == NULL)
{
std::cout << "data " << *temp
<< " is non-existent" << std::endl;
return false;
}
if (a->left == NULL)
TransplantChildTree(root, a, a->right);
else if (a->right == NULL)
TransplantChildTree(root, a, a->left);
else
{
auto temp = Minimum(a->right);
if (temp != a->right)
{
TransplantChildTree(root, temp, temp->right);
temp->right = a->right;
a->right->p = temp;
}
TransplantChildTree(root, a, temp);
temp->left = a->left;
a->left->p = temp;
}
delete a;
return true;
}
//Inorder Traversal
template <typename T>
inline void BST<T>::InorderTreeWalk()const
{
auto x = root;
std::stack<decltype(x)> temp;
while (x != NULL || !temp.empty())
{
while (x != NULL)
{
temp.push(x);
x = x->left;
}
if (!temp.empty())
{
x = temp.top();
std::cout << *x->data << " ";
x = x->right;
temp.pop();
}
}
std::cout << std::endl;
}
template <typename T>
inline void BST<T>::DeleteWholeTree()
{
auto x = root;
std::stack<decltype(x)> temp;
std::stack<decltype(x)> pointer;
while (x != NULL || !temp.empty())
{
while (x != NULL)
{
temp.push(x);
x = x->left;
}
if (!temp.empty())
{
x = temp.top();
pointer.push(x);
x = x->right;
temp.pop();
}
}
while (!pointer.empty())
{
delete pointer.top();
pointer.pop();
}
}