5.1 BinNode Binary Tree Node

Reference blog: https://blog.csdn.net/weixin_41698717/article/details/107541482
BinNode binary tree node

5.1.1 BinNode-template class

#include<iostream>
#define BinNodePosi(T) BinNode<T>* //节点位置
#define stature(p) ((p)?(p)->height:-1)//节点高度,与空树高度为-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){
    
    }
	BinNode(T e, BinNodePosi(T) p = NULL, BinNodePosi(T) lc = NULL, BinNodePosi(T) rc = NULL, int h = 0):
		data(e), parent(p), lc(lc), rc(rc), height(h) {
    
    }

	//操作接口
	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 travPOost(VST&); //后序遍历
	//比较器、判等器
	bool operator < (BinNode const& bn){
    
    
		return data < bn.data;
	}
	bool operator > (BinNode const& bn){
    
    
		return data > bn.data;
	}
	bool operator == (BinNode const& bn){
    
    
		return data == bn.data;
	}
    bool operator!=(const BinNode& bn) {
    
     return data != bn.data; }	//不等于
};

5.1.2 Shortcut (judgment by macro definition)

#define BinNodePosi(T) BinNode<T>*	//节点位置
#define stature(p) ((p)?(p)->height:-1)	//节点高度(与“空树高度为-1”的约定相统一)
typedef enum{
    
    RB_RED,RB_BLACK} RBColor;	//节点颜色
/*************************************************************************************
*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) sibling((x)->parent)	//叔叔
#define FromParentTo(x) /*来自父亲的引用*/\
	(IsRoot(x)?_root:(IsLChild(x)?(x).parent->lc:(x).parent->rc))
 
#define IsBlack(p) (!(p) || (RB_BLACK == (p)->color))	//外部节点也视作黑节点
#define IsRed(p) (!IsBlack(p))	//非黑即红
#define BlackHeightUpdated(x) (/*RedBlack高度更新条件*/ \
	(stature((x).lc)==stature((x).rc)) && \
	((x).height == (IsRed(&x)?stature((x).lc):stature((x).lc)+1)) \
)

5.1.3 size interface implementation

template <typename T>
int BinNode<T>::size(){
    
    
	int s = 1;//计入本身
	if (lChild) s += lChild->size();
	if (rChild) s += rChile->size();
	return s;
}

5.1.4 Insert child node

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

5.1.5 The immediate successor of the current node (the order is judged by the middle order traversal)

template <typename T>
BinNodePosi(T) BinNode<T>::succ() {
    
    //定位节点V的直接后继
 BinNodePosi(T) s = this;
 if ( rc ) {
    
     //若有右孩子,则
    s = rc; //直接后继必是右子树中的
    while ( HasLChild( * s ) )
        s = s->lc; //最小节点
    }else {
    
     //否则后继应是“以当前节点为直接前驱者”
 while ( IsRChild( * s ) ){
    
    
    s = s->parent; //不断朝左上移动
 }
 	s = s->parent; //最后再朝右上移动一步可能是NULL
 }
 return s; //两种情况下,运行时间分别为
} //当前节点的高度不深度,丌过O(h)

5.1.6 Traverse

Level traversal

 template <typename T> template <typename VST> 
 void BinNode<T>::travLevel( VST & visit ) {
    
     //二叉树层次遍历
 queue< BinNodePosi(T) > Q; //引入辅助队列
 Q.push( this ); //根节点入队
 while ( ! Q.empty() ) {
    
     //在队列再次变空之前,反复迭代
 BinNodePosi(T) x = Q.front(); //取出队首节点,并随即
   Q.pop();
 visit( x->data ); //访问之
 if ( HasLChild( * x ) ) Q.enqueue( x->lc ); //左孩子入队
 if ( HasRChild( * x ) ) Q.enqueue( x->rc ); //右孩子入队
 } }

In-order traversal

 template <typename T> template <typename VST>//元素类型操作器
 void BinNode<T>::travIn(VST& visit){
    
    //二叉树中序遍历统一入口
    /*switch(rand()%5) */
    switch(4){
    
    
    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;
    }
 }
 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;
        }

    }
 }

5.1.7 BinNode.h

#pragma once
#define BinNodePosi(T) BinNode<T>* //节点位置
#define stature(p) ((p) ? (p)->height: -1) //节点高度

//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))

#define sibling(p) (IsLChild(*(p))?(p)->parent->rc:(p)->parent->lc)	//兄弟
#define uncle(x) sibling((x)->parent)	//叔叔

#define FromParentTo(x)  ( IsRoot(x) ? this->_root : ( IsLChild(x) ? (x).parent->lc : (x).parent->rc ) )         //来自父亲的引用


typedef enum {
    
     RB_RED, RB_BLACK } RBColor; //节点颜色

template <typename T> struct BinNode{
    
    
	BinNodePosi(T) parent;
	BinNodePosi(T) lc;
	BinNodePosi(T) rc; //父亲、孩子
    int npl;
    RBColor color;
	T data; int height;  //高度、子树规模
    //构造函数
    BinNode():
        parent( nullptr ), lc( nullptr ),rc( nullptr ),height ( 0 ),npl( 1 ),color ( RB_RED ) {
    
    }
    BinNode( T e, BinNodePosi(T) p = nullptr, BinNodePosi(T) lc = nullptr, BinNodePosi(T) rc = nullptr, int h = 0, int l = 1, RBColor c = RB_RED):
        data( e ), parent( p ), lc( lc ), rc( rc ),height ( h ),npl( 1 ),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 &); //子树后序遍历
};

//作为左孩子插入
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);}

//size()
template <typename T> int BinNode<T>::size(){
    
    //后代总数,以其为根的子树的规模
	int s = 1; //计入本身
	if (lc) s += lc->size(); //递归计入左子树规模
	if (rc) s += rc->size(); //递归计入右子树规模
	return s;
}//O(n=|size|)


template <typename T>
BinNodePosi(T) BinNode<T>::succ() {
    
    //定位节点V的直接后继
 BinNodePosi(T) s = this;
 if ( rc ) {
    
     //若有右孩子,则
    s = rc; //直接后继必是右子树中的
    while ( HasLChild( * s ) )
        s = s->lc; //最小节点
    }else {
    
     //否则后继应是“以当前节点为直接前驱者”
 while ( IsRChild( * s ) ){
    
    
    s = s->parent; //不断朝左上移动
 }
 	s = s->parent; //最后再朝右上移动一步可能是NULL
 }
 return s; //两种情况下,运行时间分别为
} //当前节点的高度不深度,过O(h)

5.1.8 release.h

//"release.h"
#pragma once

#ifdef _DEBUG
#include <stdio.h>
#include <typeinfo>
#endif

/******************************************************************************************
 * 列表、向量等结构内的节点中,可以存放基本类型或构造类型
 * 按照本书约定,出于效率的考虑,对于后一情况通常只保存对象的指针
 * 因此,在主体结构析构之前,需要首先释放这些成员对象所占的空间
 * 此处,借助C++中偏特化技术区分上述两种情况,并做对应处理
 ******************************************************************************************/

namespace dtl 
{
    
    

template <typename T> 
struct Cleaner {
    
    
   static void clean ( T x ) {
    
     //相当于递归基
#ifdef _DEBUG
      static int n = 0;
      if ( 7 > strlen ( typeid ( T ).name() ) ) {
    
     //复杂类型一概忽略,只输出基本类型
         printf ( "\t<%s>[%d]=", typeid ( T ).name(), ++n );
         //print ( x );
         printf ( " purged\n" );
      }
#endif
   }
};

template <typename T> 
struct Cleaner<T*> {
    
    
   static void clean ( T* x ) {
    
    
      if ( x ) {
    
     delete x; } //如果其中包含指针,递归释放
#ifdef _DEBUG
      static int n = 0;
      printf ( "\t<%s>[%d] released\n", typeid ( T* ).name(), ++n );
#endif
   }
};

template <typename T> 
inline void release ( T x ) {
    
     Cleaner<T>::clean ( x ); }

}

Guess you like

Origin blog.csdn.net/ZXG20000/article/details/113746004