#include <iostream>
#include "stack.hpp"
using namespace std;
#define BinNodePosi(T) BinNode<T> *
#define stature(p) ((p) ? (p)->height : -1)
typedef enum
{
RB_RED,
RB_BLACK
} RBColor;
template <typename T>
struct BinNode
{
T data;
BinNodePosi(T) parent;
BinNodePosi(T) lc;
BinNodePosi(T) rc;
int height;
int npl;
RBColor color;
BinNode() : parent(NULL), lc(NULL), rc(NULL), height(0), npl(1), color(RB_RED) {}
BinNode(T e, BinNodePosi(T) p = NULL, BinNodePosi(T) lc = NULL, BinNodePosi(T) rc = NULL, int h = 0, int l = 1, RBColor c = RB_RED) : data(e), parent(p), lc(lc), rc(rc), height(h), npl(l), color(c) {}
int size();
BinNodePosi(T) insertAsLC(T const &);
BinNodePosi(T) insertAsRC(T const &);
BinNodePosi(T) succ();
template <typename VST>
void travLevel(VST &);
template <typename VST>
void travPre(VST &);
template <typename VST>
void travIn(VST &);
template <typename VST>
void travPost(VST &);
bool operator<(BinNode const &bn) { return data < bn.data; }
bool operator==(BinNode const &bn) { return data == bn.data; }
};
/******************************************************************************************
* BinNode状态与性质的判断
******************************************************************************************/
#define IsRoot(x) (!((x).parent))
#define IsLChild(x) (!IsRoot(x) && (&(x) == (x).parent->lc))
#define IsRChild(x) (!IsRoot(x) && (&(x) == (x).parent->rc))
#define HasParent(x) (!IsRoot(x))
#define HasLChild(x) ((x).lc)
#define HasRChild(x) ((x).rc)
#define HasChild(x) (HasLChild(x) || HasRChild(x)) // 至少拥有一个孩子
#define HasBothChild(x) (HasLChild(x) && HasRChild(x)) // 同时拥有两个孩子
#define IsLeaf(x) (!HasChild(x))
/******************************************************************************************
* 与BinNode具有特定关系的节点及指针
******************************************************************************************/
#define sibling(p) /*兄弟*/ \
(IsLChild(*(p)) ? (p)->parent->rc : (p)->parent->lc)
#define uncle(x) /*叔叔*/ \
(IsLChild(*((x)->parent)) ? (x)->parent->parent->rc : (x)->parent->parent->lc)
#define FromParentTo(x) /*来自父亲的引用*/ \
(IsRoot(x) ? _root : (IsLChild(x) ? (x).parent->lc : (x).parent->rc))
template <typename T>
BinNodePosi(T) BinNode<T>::insertAsLC(T const &e)
{
return lc = new BinNode(e, this);
}
template <typename T>
BinNodePosi(T) BinNode<T>::insertAsRC(T const &e)
{
return rc = new BinNode(e, this);
}
template <typename T>
template <typename VST> // 元素类型、操作器
void BinNode<T>::travIn(VST &visit)
{ // 二叉树中序遍历算法统一入口
switch (rand() % 5)
{ // 此处暂随机选择以做测试,共五种选择
case 1:
travIn_I1(this, visit);
break; // 迭代版#1
case 2:
travIn_I2(this, visit);
break; // 迭代版#2
case 3:
travIn_I3(this, visit);
break; // 迭代版#3
case 4:
travIn_I4(this, visit);
break; // 迭代版#4
default:
travIn_R(this, visit);
break; // 递归版
}
}
template <typename T>
class BinTree
{
protected:
int _size;
BinNodePosi(T) _root;
virtual int updateHeight(BinNodePosi(T) x);
void updateHeightAbove(BinNodePosi(T) x);
public:
BinTree() : _size(0), _root(NULL) {}
~BinTree()
{
if (0 < _size)
remove(_root);
}
int size() const { return _size; }
bool empty() const { return !_root; }
BinNodePosi(T) root() const { return _root; }
BinNodePosi(T) insertAsRoot(T const &e);
BinNodePosi(T) insertAsLC(BinNodePosi(T) x, T const &e);
BinNodePosi(T) insertAsRC(BinNodePosi(T) x, T const &e);
BinNodePosi(T) attachAsLC(BinNodePosi(T) x, BinTree<T> *&);
BinNodePosi(T) attachAsRC(BinNodePosi(T) x, BinTree<T> *&);
int remove(BinNodePosi(T) x);
BinTree<T> *secede(BinNodePosi(T) x);
template <typename VST>
void travLevel(VST &visit)
{
if (_root)
_root->travLevel(visit);
}
template <typename VST>
void travPre(VST &visit)
{
if (_root)
_root->travPre(visit);
}
template <typename VST>
void travIn(VST &visit)
{
if (_root)
_root->travIn(visit);
}
template <typename VST>
void travPost(VST &visit)
{
if (_root)
_root->travPost(visit);
}
bool operator<(BinTree<T> const &t)
{
return _root && t._root && lt(_root, t._root);
}
bool operator==(BinTree<T> const &t)
{
return _root && t._root && (_root == t._root);
}
};
template <typename T>
int BinTree<T>::updateHeight(BinNodePosi(T) x)
{
return x->height = 1 + max(stature(x->lc), stature(x->rc));
}
template <typename T>
void BinTree<T>::updateHeightAbove(BinNodePosi(T) x)
{
while (x)
{
updateHeight(x);
x = x->parent;
}
}
template <typename T>
BinNodePosi(T) BinTree<T>::insertAsRoot(T const &e)
{
_size = 1;
return _root = new BinNode<T>(e);
}
template <typename T>
BinNodePosi(T) BinTree<T>::insertAsLC(BinNodePosi(T) x, T const &e)
{
_size++;
x->insertAsLC(e);
updateHeightAbove(x);
return x->lc;
}
template <typename T>
BinNodePosi(T) BinTree<T>::insertAsRC(BinNodePosi(T) x, T const &e)
{
_size++;
x->insertAsRC(e);
updateHeightAbove(x);
return x->rc;
}
template <typename T>
BinNodePosi(T) BinTree<T>::attachAsLC(BinNodePosi(T) x, BinTree<T> *&S)
{
if (x->lc = S->_root)
x->lc->parent = x;
_size += S->_size;
updateHeightAbove(x);
S->_root = NULL;
S->_size = 0;
release(S);
S = NULL;
return x;
}
template <typename T>
BinNodePosi(T) BinTree<T>::attachAsRC(BinNodePosi(T) x, BinTree<T> *&S)
{
if (x->rc = S->_root)
x->rc->parent = x;
_size += S->_size;
updateHeightAbove(x);
S->_root = NULL;
S->_size = 0;
release(S);
S = NULL;
return x;
}
template <typename T>
int BinTree<T>::remove(BinNodePosi(T) x)
{
FromParentTo(*x) = NULL;
updateHeightAbove(x->parent);
int n = removeAt(x);
_size -= n;
return n;
}
template <typename T>
static int removeAt(BinNodePosi(T) x)
{
if (!x)
return 0;
int n = 1 + removeAt(x->lc) + removeAt(x->rc);
release(x->data);
release(x);
return n;
}
template <typename T>
BinTree<T> *BinTree<T>::secede(BinNodePosi(T) x)
{
FromParentTo(*x) = NULL;
updateHeightAbove(x->parent);
BinTree<T> *S = new BinTree<T>;
S->_root = x;
x->parent = NULL;
S->_size = x->size();
_size -= S->_size;
return S;
}
template <typename T, typename VST>
void travPre_R(BinNodePosi(T) x, VST &visit)
{
if (!x)
return;
visit(x->data);
travPre_R(x->lc, visit);
travPre_R(x->rc, visit);
}
template <typename T, typename VST>
void travPre_R(BinNodePosi(T) x, VST &visit)
{
if (!x)
return;
travPre_R(x->lc, visit);
travPre_R(x->rc, visit);
visit(x->data);
}
template <typename T, typename VST>
void travPre_R(BinNodePosi(T) x, VST &visit)
{
if (!x)
return;
travPre_R(x->lc, visit);
visit(x->data);
travPre_R(x->rc, visit);
}
template <typename T, typename VST>
static void visitAlongLeftBranch(BinNodePosi(T) x, VST &visit, Stack<BinNodePosi(T)> &S)
{
while (x)
{
visit(x->data);
S.push(x->rc);
x = x->lc;
}
}
template <typename T, typename VST>
void travPre_I1(BinNodePosi(T) x, VST &visit)
{
Stack<BinNodePosi(T)> S;
if (x)
S.push(x);
while (!S.empty())
{
x = S.pop();
visit(x->data);
if (HasRChild(*x))
S.push(x->rc);
if (HasLChild(*x))
S.push(x->lc);
}
}
template <typename T, typename VST>
void travPre_I2(BinNodePosi(T) x, VST &visit)
{
Stack<BinNodePosi(T)> S;
while (true)
{
visitAlongLeftBranch(x, visit, S);
if (S.empty())
break;
x = S.pop();
}
}
template <typename T>
static void goAlongLeftBranch(BinNodePosi(T) x, Stack<BinNodePosi(T)> &S)
{
while (x)
{
S.push(x);
x = x->lc;
}
}
template <typename T, typename VST>
void travIn_I1(BinNodePosi(T) x, VST &visit)
{
Stack<BinNodePosi(T)> S;
while (true)
{
goAlongLeftBranch(x, S);
if (S.empty())
break;
x = S.pop();
visit(x->data);
x = x->rc;
}
}
template <typename T>
BinNodePosi(T) BinNode<T>::succ()
{
BinNodePosi(T) s = this;
if (rc)
{
s = rc;
while (HasLChild(*s))
s = s->lc;
}
else
{
while (IsRChild(*s))
s = s->parent;
}
return s;
}
template <typename T, typename VST>
void travIn_I2(BinNodePosi(T) x, VST &visit)
{
Stack<BinNodePosi(T)> S;
while (true)
{
if (x)
{
S.push(x);
x = x->lc;
}
else if (!S.empty())
{
x = S.pop();
visit(x->data);
x = x->rc;
}
else
break;
}
}
template <typename T, typename VST>
void travIn_I3(BinNodePosi x, VST &visit)
{
bool backtrack = false;
while (true)
{
if (!backtrack && HasChild(*x))
x = x->lc;
else
{
visit(x->data);
if (HasRChild(*x))
{
x = x->rc;
backtrack = false;
}
else
{
if (!(x = x->succ()))
break;
backtrack = true;
}
}
}
}
template <typename T, typename VST>
void travIn_I4(BinNodePosi(T) x, VST &visit)
{
while (true)
if (HasLChild(*x))
x = x->lc;
else
{
visit(x->data);
while (!HasRChild(*x))
if (!(x = x->succ()))
return;
else
visit(x->data);
x = x->rc;
}
}
template <typename T>
static void gotoHLVFL(Stack<BinNodePosi(T)> &S)
{
while (BinNodePosi(T) x = S.top())
if (HasLChild(*x))
{
if (HasRChild(*x))
S.push(x->rc);
S.push(x->lc);
}
else
S.push(x->rc);
S.pop();
}
template <typename T, typename VST>
void travPost_I(BinNodePosi(T) x, VST &visit)
{
Stack<BinNodePosi(T)> S;
if (x)
S.push(x);
while (!S.empty())
{
if (S.top() != x->parent)
gotoHLVFL(S);
x = S.pop();
visit(x->data);
}
}
template <typename T>
template <typename VST>
void BinNode<T>::travLevel(VST &visit)
{
Queue<BinNodePosi(T)> Q;
Q.enqueue(this);
while (!Q.empty())
{
BinNodePosi(T) x = Q.dequeue();
visit(x->data);
if (HasLChild(*x))
Q.enqueue(x->lc);
if (HasRChild(*x))
Q.enqueue(x->rc);
}
}