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