1. 程式人生 > >資料結構 二叉樹《c++版》

資料結構 二叉樹《c++版》

二叉樹節點BinNode模板類

#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), 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 的操作做一歸納整理


 /******************************************************************************************
  * 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))
	
	/******************************************************************************************
		 0015  * 與BinNode具有特定關係的節點及指標
		 0016  ******************************************************************************************/
	 #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); } //將e作為當前節點的左孩子插入二叉樹

template <typename T> BinNodePosi(T) BinNode<T>::insertAsRC(T const& e)
{ return rc = new BinNode(e, this); } //將e作為當前節點的右孩子插入二叉樹

二叉樹遍歷演算法統一入口

 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; //遞迴版
	
	}
	
}