bstree.h
#ifndef TEMPLATE_BSTREE_H_
#define TEMPLATE_BSTREE_H_
#include <iostream>
#include <stack>
#include <vector>
using std::cout;
using std::endl;
using std::stack;
using std::vector;
namespace bstree
{
template<typename T>
struct Node
{
T key;
Node<T> *left;
Node<T> *right;
Node<T> *parent;
Node(const T k) : key(k), left(NULL), right(NULL), parent(NULL)
{ }
};
template<typename T>
class Bstree
{
public:
Bstree() { root = NULL; }
~Bstree() { }
void BstInsert(T val);
void BstInOrder(Node<T> *t);
void BstInOrder();
Node<T> *BstSearch(const T val);
Node<T> *BstMin(Node<T> *t);
Node<T> *BstMax(Node<T> *t);
Node<T> *BstSuccessor(Node<T> *t);
void BstDelete(const T val);
void BstClear();
private:
Node<T> *root;
};
template<typename T>
void Bstree<T>::BstInsert(T val)
{
Node<T> *dst = NULL;
Node<T> *tmp = root;
Node<T> *fresh = new Node<T>(val);
if (NULL == fresh)
return ;
while (NULL != tmp)
{
dst = tmp;
if (val < tmp->key)
tmp = tmp->left;
else
tmp = tmp->right;
}
if (NULL == dst) // empty tree before
{
root = fresh;
}
else
{
fresh->parent = dst;
if (val < dst->key)
dst->left = fresh;
else
dst->right = fresh;
}
}
template<typename T>
void Bstree<T>::BstInOrder(Node<T> *t)
{
if (NULL != t)
{
BstInOrder(t->left);
cout << t->key << " ";
BstInOrder(t->right);
}
}
template<typename T>
void Bstree<T>::BstInOrder()
{
Node<T> *t = root;
BstInOrder(t);
}
template<typename T>
Node<T> * Bstree<T>::BstSearch(const T val)
{
Node<T> *t = root;
while (NULL != t && val != t->key)
{
if (val < t->key)
t = t->left;
else
t = t->right;
}
return t;
}
template<typename T>
Node<T> * Bstree<T>::BstMin(Node<T> *t)
{
while (NULL != t->left)
t = t->left;
return t;
}
template<typename T>
Node<T> * Bstree<T>::BstMax(Node<T> *t)
{
while (NULL != t->right)
t = t->right;
return t;
}
/* Get successor of t under the condition of InOrderTravel */
template<typename T>
Node<T> * Bstree<T>::BstSuccessor(Node<T> *t)
{
if (NULL != t->right)
return BstMin(t->right);
Node<T> *p = t->parent;
while (NULL != p && t == p->right)
{
t = p;
p = p->parent;
}
return p;
}
template<typename T>
void Bstree<T>::BstDelete(const T val)
{
Node<T> *dst = BstSearch(val);
if (NULL == dst)
{
cout << "does not find the " << val << endl;
return ;
}
Node<T> *lson = dst->left;
Node<T> *rson = dst->right;
if (NULL != lson && NULL != rson)
{
Node<T> *suc = BstSuccessor(dst);
dst->key = suc->key;
if (NULL == suc->right)
suc->parent->right = NULL;
else if (NULL != suc->right && dst == suc->parent)
dst->right = suc->right;
else if (suc == suc->parent->left)
suc->parent->left = (NULL != suc->right ? suc->right : NULL);
delete suc;
suc = NULL;
}
else if (NULL == lson && NULL == rson)
{
if (dst == dst->parent->left)
dst->parent->left = NULL;
else if (dst == dst->parent->right)
dst->parent->right = NULL;
delete dst;
dst = NULL;
}
else
{
if (dst == dst->parent->left)
dst->parent->left = (NULL != dst->left ? dst->left : dst->right);
else
dst->parent->right = (NULL != dst->right ? dst->right : dst->left);
delete dst;
dst = NULL;
}
}
/* use PreOrder way to Clear */
template<typename T>
void Bstree<T>::BstClear()
{
stack<Node<T> *> st;
vector<Node<T> *> vec;
Node<T> *t = root;
Node<T> *tmp = t;
while (NULL != t || !st.empty())
{
if (NULL != t)
{
vec.push_back(t);
st.push(t);
t = t->left;
}
else
{
tmp = st.top();
st.pop();
t = tmp->right;
}
}
typename std::vector<Node<T> *>::iterator it = vec.begin();
for (; it != vec.end(); ++it)
{
cout << "delete " << (*it)->key << endl;
delete (*it);
*it = NULL;
}
vec.clear();
}
}
#endif
main.cpp
#include "bstree.h"
using namespace::bstree;
int main()
{
Bstree<int> bst;
int arr[12] = {15, 6, 3, 2, 4, 7, 13, 9, 18, 16, 17, 20};
for (int i = 0; i < 12; ++i)
bst.BstInsert(arr[i]);
bst.BstInOrder();
cout << endl;
bst.BstDelete(4);
cout << "After delete 15" << endl;
bst.BstInOrder();
cout << endl;
bst.BstClear();
return 0;
}