节点

BinNode.h

#include <iostream>
#include "Queue.hpp"

#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; //Null Path Length(左式堆,也可直接用height代替)
    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,_root) ( 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);
}

//定位节点V的直接后继(中序遍历序列)
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;
        }
        s = s -> parent;
    }
    
    return s;
}


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);
        }
    }
    
}

template <typename T> template <typename VST>
void BinNode<T>::travPre(VST&){  //子树先序遍历
    
}

template <typename T> template <typename VST>
void BinNode<T>::travIn(VST&visit){ //子树中序遍历
    switch ( rand() % 5) {
        case 1:
            travIn_I1(this, visit);
            break;
            
        case 2:
            travIn_I2(this, visit);
            break;
            
        case 3:
            travIn_I3(this, visit);
            break;
            
        case 4:
            travIn_I4(this, visit);
            break;
            
        default:
            travIn_R(this, visit);
            break;
    }
}

BinTree.h

#include "BinNode.hpp"
#include "Stack.hpp"

template <typename T> class BinTree {
protected:
    int _size;
    BinNodePosi(T) _root;
    virtual int updateHeight(BinNodePosi(T) x);  //更新节点x的高度
    void updateHeightAbove(BinNodePosi(T) x);  //更新节点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); //e作为x的左孩子插入
    BinNodePosi(T) insertAsRC(BinNodePosi(T) x,T const& e); //e作为x的右孩子插入
    BinNodePosi(T) attachAsLC(BinNodePosi(T) x,BinTree<T>* &t); //t作为x的左子树接入
    BinNodePosi(T) attachAsRC(BinNodePosi(T) x,BinTree<T>* &t);//t作为右子树插入
    
    int remove(BinNodePosi(T) x); //删除以位置x除节点为根的子树,返回该子树原先的规模
    BinTree<T>* secede(BinNodePosi(T) x); //将子树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 + std::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) {
    //二叉树子树接入算法:将S当作节点x的左子树接入,S本身置空
    if ((x -> lc = S -> _root)) {
        x -> lc -> parent = x;
    }
    
    _size += S -> _size;
    updateHeightAbove(x);
    S->_root = NULL;
    S->_size = 0;
    
    //    release(S);
    delete 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);
    delete S;
    
    S = NULL;
    return x;
}


//子树删除
template <typename T>
int BinTree<T>::remove(BinNodePosi(T) x){
    //assert: x为二叉树中的合法位置
    FromParentTo(*x, this->_root) = NULL;  //切断来自父节点的指针
    updateHeightAbove(x->parent);  //更新祖先高度
    int n = removeAt(x);
    _size -= n;
    return n;
}


//删除二叉树中位置x处的节点及其后代,返回被删除节点的数值
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);
    delete x;
    return n;
}

//子树分离
//将子树x从当前树中摘除,将其封装为一棵独立子树返回
template <typename T>
BinTree<T>* BinTree<T>::secede(BinNodePosi(T) x){
    //assert: x为二叉树中的合法位置
    FromParentTo(*x, this->_root) = 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;
}


//遍历
//1.递归式遍历
//1.1 先序遍历
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);
}

//1.2 后序遍历
template <typename T,typename VST>
void travPost_R(BinNodePosi(T) x,VST& visit) {
    if (!x) {
        return;
    }
    travPost_R(x -> lc, visit);
    travPost_R(x -> rc, visit);
    visit(x -> data);
}

//1.3 中序遍历
template <typename T,typename VST>
void travIn_R(BinNodePosi(T) x, VST& visit){
    if (!x) {
        return;
    }
    
    travIn_R(x -> lc, visit);
    visit(x -> data);
    travIn_R(x -> rc, visit);
}

//2.迭代式遍历
//2.1 先序遍历
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>
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 trav_Pre_I2(BinNodePosi(T) x,VST& visit) {
    Stack<BinNodePosi(T)> S;  //辅助栈
    
    while (true) {
        visitAlongLeftBranch(x, visit, S);
        if (S.empty()) {
            break;
        }
        x = S.pop();
    }
}

//2.2 中序遍历
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,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(T) x,VST& visit){
    bool backtrack = false; //前一步是否刚从右子树回溯----省去栈,仅σ(1)辅助空间
    while (true) {
        if (!backtrack && HasLChild(*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;
        }
        
    }
}


//2.3 后序遍历
//在以S栈顶节点为根的子树中,找到最高左侧可见叶节点
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);
    }
}

 

posted on 2018-11-11 21:44  迷心迷  阅读(226)  评论(0编辑  收藏  举报