二叉树

#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);
    }
}
posted @ 2025-07-03 16:41  张诗羽  阅读(13)  评论(0)    收藏  举报