二叉树系列包括二叉树基类、二叉搜索树、红黑树以及AVL树。这里先讨论二叉树基类。
先看BTNode类的定义
template
<
class
T
>
struct
BTNode

...
{
BTNode(T d, COLOR c = RED, BF f = NORMAL, BTNode* l = nil_, BTNode* r = nil_, BTNode* p = nil_)

: data_(d), color_(c), factor_(f), lchild_(l), rchild_(r), parent_(p) ...{}

BTNode *lchild_, *rchild_, *parent_;
int color_, factor_;
T data_;


static BTNode* nil() ...{ return nil_; }
// use singleton pattern
static BTNode* createNil()

...{
if (nil_ == BTNode<T>::nil())

...{
nil_ = new BTNode();
nilify(nil_);
}
return nil_;
}
// nilify the node
static void nilify(BTNode* x = nil_)

...{
x->lchild_ = nil_;
x->rchild_ = nil_;
x->parent_ = nil_;
x->color_ = BLACK;
x->factor_ = NORMAL;
}

static void increment() ...{ refcnt_++; }

static void decrement() ...{ if (--refcnt_ == 0) delete nil_; }

private:

BTNode() : data_(T(0)), color_(RED), factor_(NORMAL), lchild_(0), rchild_(0), parent_(0) ...{}
static BTNode* nil_;
static int refcnt_;
}
;
这里增加了Nil节点的操作。Nil节点的增加是为了在派生类红黑树中的实现。这些操作包括了该节点的创建,该节点的引用访问以及该节点的删除。引用计数的增加使所有红黑树的叶子节点和根节点都指向了同一个Nil节点,便于红黑树的实现。
在BTree类中,主要包括了有关二叉树的一些基本操作,如二叉树的构造,二叉树的销毁以及二叉树的打印。这里值得一提的是二叉树的打印,它是按照二叉树的树形结构来打印的,看起来比较直观。对于红黑树和AVL树的调试,树形打印提供了很大的方便。
完整的代码为(BTree.h):
#ifndef _BINARY_TREE_H_
#define
_BINARY_TREE_H_

#include
<
queue
>
#include
<
iomanip
>
#include
<
iostream
>
using
std::setw;
using
std::cout;
using
std::queue;
using
std::ostream;


enum
COLOR
...
{ RED = 0, BLACK }
;

enum
BF
...
{ LOW = -2, LESS, NORMAL, MORE, HIGH }
;

template
<
class
T
>
struct
BTNode

...
{
BTNode(T d, COLOR c = RED, BF f = NORMAL, BTNode* l = nil_, BTNode* r = nil_, BTNode* p = nil_)

: data_(d), color_(c), factor_(f), lchild_(l), rchild_(r), parent_(p) ...{}

BTNode *lchild_, *rchild_, *parent_;
int color_, factor_;
T data_;


static BTNode* nil() ...{ return nil_; }
// use singleton pattern
static BTNode* createNil()

...{
if (nil_ == BTNode<T>::nil())

...{
nil_ = new BTNode();
nilify(nil_);
}
return nil_;
}
// nilify the node
static void nilify(BTNode* x = nil_)

...{
x->lchild_ = nil_;
x->rchild_ = nil_;
x->parent_ = nil_;
x->color_ = BLACK;
x->factor_ = NORMAL;
}

static void increment() ...{ refcnt_++; }

static void decrement() ...{ if (--refcnt_ == 0) delete nil_; }

private:

BTNode() : data_(T(0)), color_(RED), factor_(NORMAL), lchild_(0), rchild_(0), parent_(0) ...{}
static BTNode* nil_;
static int refcnt_;
}
;

template
<
class
T
>
BTNode
<
T
>*
BTNode
<
T
>
::nil_
=
BTNode
<
T
>
::nil();
template
<
class
T
>
int
BTNode
<
T
>
::refcnt_
=
0
;

template
<
class
T
>
class
BTree

...
{
public:
BTree(T data = T())

...{
BTNode<T>::createNil();
BTNode<T>::increment();
root_ = new BTNode<T>(data);
BTNode<T>::nilify(root_);
}

virtual ~BTree() ...{ destroy(root_); BTNode<T>::decrement(); }

int height() const ...{ return height(root_); }

void print(ostream& out) ...{ print(out, root_); }

protected:
BTNode<T>* root_;

private:
int height(BTNode<T>* x) const

...{
if (x == BTNode<T>::nil()) return 0;
int hl = height(x->lchild_);
int hr = height(x->rchild_);
if (hl > hr) return ++hl;
else return ++hr;
}
void destroy(BTNode<T>* x)

...{
if (x != BTNode<T>::nil())

...{
destroy(x->lchild_);
destroy(x->rchild_);
delete x;
}
}
void print(ostream& out, BTNode<T>* p)

...{
queue<BTNode<T>* > node;
int level = 0, h = height(p) - 1;

for ( int i = 1; i < 2<<h; i++)

...{
// specify the print format
if (i == 1<<level) out << endl << setw(2 << (h - level++));
else out << setw(4 << (h - level + 1));

// print the data, '-' for nil node
if (p != BTNode<T>::nil()) out << p->data_;
else out << '-';

// push the left and right child
node.push(p->lchild_); node.push(p->rchild_);

// pop the node to print
p = node.front(); node.pop();
}
}
}
;

template
<
class
T
>
ostream
&
operator
<<
(ostream
&
out
, BTree
<
T
>&
bt)

...
{
bt.print(out);
return out;
}

#endif