本文给出二叉搜索树的C++实现,在一部分教材中二叉搜索树又称二叉排序树,这种树结构存在多种变种,比如BBST,AVLTree,RBTree,等,其作用是对一系列数据进行合理的布局使得按照中序遍历出来的结果序列是按照关键码值升序排列,从而使得对某一个元素的访问效率尽可能的接近对数时间复杂度,但是就本文所提及的简单BST而言,并没有对任一节点进行左右子树平衡化处理,所以在某些极端的情况下BST就退化为一个“链表”式的“斜树”,所以单纯从效率而言,未经优化过的BST不论是在插入亦或是访问,删除等操作都不能达到我们所满意的效果,为了解决这一问题,人们又相继提出了AVL,RBTree等等数据结构,分别采用不同的策略使得前面所提及的操作尽可能的得到时间上的优化。
#include"BinTree.h"
using namespace std;
template <typename T>
class BST : public BinTree<T>
{
protected:
BinNodePosi(T) _hot;
public:
virtual BinNodePosi(T)& search(const T& e);
virtual BinNodePosi(T) insert(const T& e);
virtual bool remove(const T& e);
virtual BinNodePosi(T) rotateAt(BinNodePosi(T) v);
virtual BinNodePosi(T) connect34(
BinNodePosi(T) a, BinNodePosi(T) b, BinNodePosi(T) c,
BinNodePosi(T) T0, BinNodePosi(T) T1, BinNodePosi(T) T2, BinNodePosi(T) T3
);
};
template <typename T> BinNodePosi(T) BST<T>::connect34(
BinNodePosi(T) a, BinNodePosi(T) b, BinNodePosi(T) c,
BinNodePosi(T) T0, BinNodePosi(T) T1, BinNodePosi(T) T2, BinNodePosi(T) T3
) {
a->lc = T0; if (T0) T0->parent = a;
a->rc = T1; if (T1) T1->parent = a; BinTree<T>::updateHeight(a);
c->lc = T2; if (T2) T2->parent = c;
c->rc = T3; if (T3) T3->parent = c; BinTree<T>::updateHeight(c);
b->lc = a; a->parent = b;
b->rc = c; c->parent = b; BinTree<T>::updateHeight(b);
return b;
}
template <typename T> BinNodePosi(T) BST<T>::rotateAt(BinNodePosi(T) v) {
if (!v) { printf("\a\nFail to rotate a null node\n"); exit(-1); }
BinNodePosi(T) p = v->parent; BinNodePosi(T) g = p->parent;
if (IsLChild(*p))
if (IsLChild(*v)) {
p->parent = g->parent;
return connect34(v, p, g, v->lc, v->rc, p->rc, g->rc);
}
else {
v->parent = g->parent;
return connect34(p, v, g, p->lc, v->lc, v->rc, g->rc);
}
else
if (IsRChild(*v)) {
p->parent = g->parent;
return connect34(g, p, v, g->lc, p->lc, v->lc, v->rc);
}
else {
v->parent = g->parent;
return connect34(g, v, p, g->lc, v->lc, v->rc, p->rc);
}
}
template <typename T>
BinNodePosi(T)& BST<T>::search(const T& e)
{
if (!BinTree<T>::_root || e == BinTree<T>::_root->data)
{
_hot = NULL;
return BinTree<T>::_root;
}
for (_hot = BinTree<T>::_root; ; )
{
BinNodePosi(T)& c = (e < _hot->data) ? _hot->lc : _hot->rc;
if (!c || e == c->data)
{
return c;
}
_hot = c;
}
}
template <typename T>
bool BST<T>::remove(const T& e)
{
BinNodePosi(T)& x = search(e);
if (!x)
{
return false;
}
removeAt(x, _hot);
BinTree<T>::_size--;
BinTree<T>::updateHeightAbove(_hot);
return true;
}
template <typename T>
static BinNodePosi(T) removeAt(BinNodePosi(T)& x, BinNodePosi(T)& hot)
{
BinNodePosi(T) w = x;
BinNodePosi(T) succ = NULL;
if (!HasLChild(*x))
{
succ = x = x->rc;
}
else if (!HasRChild(*x))
{
succ = x = x->lc;
}
else
{
w = w->succ();
swap(x->data, w->data);
BinNodePosi(T) u = w->parent;
((u == x) ? u->rc : u->lc) = succ = w->rc;
}
hot = w->parent;
if (succ)
{
succ->parent = hot;
}
release(w->data);
release(w);
return succ;
}
template <typename T>
BinNodePosi(T) BST<T>::insert(const T& e)
{
BinNodePosi(T)& x = search(e);
if (x)
{
return x;
}
x = new BinNode<T>(e, _hot);
BinTree<T>::_size++;
BinTree<T>::updateHeightAbove(x);
return x;
}
template<typename T>
static BinNodePosi(T)& searchIn(BinNodePosi(T)& v, const T& e, BinNodePosi(T)& hot)
{
if (!v || (e == v->data))
{
return v;
}
hot = v;
return searchIn(((e < v->data) ? v->lc : v->rc), e, hot);
}
int main()
{
BST<int>obj;
obj.insert(1);
obj.insert(10);
obj.insert(5);
obj.travIn(visit<int>);
cout << endl;
if (!obj.search(5))
{
cout << "element 5 not found!" << endl;
}
obj.remove(1);
if (obj.empty())
{
cout << "Tree is empty"<<endl;
}
getchar();
return 0;
}