樹T中全部節點深度的最大值稱爲該樹的高度(height),實際上每一個節點與其全部子節點均可以看作一顆樹,也就是說除了根結點,全部子結點均可以看作是一顆子樹,所以每一個結點都有樹高。在本程序中約定,僅含單個結點的樹高爲0,空樹高度爲-1。據此,編寫getHight():node
int getHight(BinNodePosi(T) x) { int l_hight,r_hight; if(x==NULL) return -1; else if(!hasChild(*x)) { return 0; } else { l_hight = getHight(x->lc)+1; r_hight = getHight(x->rc)+1; } return l_hight>r_hight?l_hight:r_hight; }
結點類定義代碼以下:ios
#ifndef BINNODE #define BINNODE #include <iostream> //*************************************************************************************** ///代碼5.2 , BinNode狀態與性質的判斷 ///1、 判斷該節點是什麼! /// 是不是根節點、是不是左子節點、是不是右子節點、是不是葉節點 #define isRoot(x) (!((x).parent)) #define isLChild(x) (!isRoot(x)&&(&(x)==(x).parent->lc)) //不是根節點,同時必須是父節點的左孩子 #define isRChild(x) (!isRoot(x)&&(&(x)==(x).parent->rc)) //不是根節點,同時必須是父節點的右孩子 ///2、判斷該節點有什麼 //判斷是否有孩子 #define hasLChild(x) ((x).lc!=NULL) //判斷節點x是否有左孩子 #define hasRChild(x) ( (x).rc ) //判斷節點x 是否有右孩子 #define hasChild(x) ( hasLChild(x)||hasRChild(x)) //判斷節點x是否有孩子(左、右至少有一個) //判斷是否爲葉節點 #define isLeaf(x) ( !hasChild(x) ) //判斷節點x是不是葉子節點 //**************************************************************************************** #define BinNodePosi(T) BinNode<T>* //節點位置 typedef enum{RB_RED,RB_BLACK} RBColor;//節點顏色 template <typename T> class BinNode { public: T data;//數值 int height; int npl;//Null Path Length(左式堆,也可直接用height代替) RBColor color; BinNodePosi(T) parent;//父節點 BinNodePosi(T) lc;//左子節點 BinNodePosi(T) rc;//右子節點 //構造函數 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; this->lc=lc,this->rc=rc;//此處添加this指針,以便將成員變量lc、rc與形參lc和rc區分 height=h; npl=l; color=c; } ///***********插入孩子節點******************************* /// 將數據e做爲當前節點的左孩子或右孩子插入,並返回該節點指針 BinNodePosi(T) insertAsLC(T const&e) { return lc=new BinNode(e,this); } BinNodePosi(T) insertAsRC(T const&e) { return rc=new BinNode(e,this); } }; #endif // BINNODE
樹的定義代碼以下:數組
#ifndef BINTREE #define BINTREE #include<binnode.h> template<typename T> class BinTree { public: int _size; BinNodePosi(T) _root;//根結點指針 int getHight(BinNodePosi(T) x) { int l_hight,r_hight; if(x==NULL) return -1; else if(!hasChild(*x)) { return 0; } else { l_hight = getHight(x->lc)+1; r_hight = getHight(x->rc)+1; } return l_hight>r_hight?l_hight:r_hight; } virtual int updateHeight(BinNodePosi(T) x)//更新節點x的高度 { } // void updateAboveHeight(BinNode<T> *x);//跟新節點x及其祖先的高度 public: BinTree():_size(0),_root(NULL){} int size()const{return _size;}//獲取樹的規模,即共有多少個節點 bool empty(){return !_root;}//判斷是否爲空樹 BinNodePosi(T) root()const{return _root;}//獲取根結點指針 BinNodePosi(T) insertAsRoot(T const&e) { _size=1; return _root=new BinNode<T>(e); } BinNodePosi(T) insertAsLC(BinNodePosi(T) x,T const&e) { _size++;x->insertAsLC(e); x->height =getHight(x); return x->lc; } BinNodePosi(T) insertAsRC(BinNodePosi(T) x,T const&e) { _size++;x->insertAsRC(e); x->height=getHight(x); return x->rc; } }; #endif // BINTREE
在測試程序中設計了六個結點的二叉樹:函數
測試程序代碼以下:測試
int main() { BinNode<string>* n[6];//數組指針 BinTree<string> bt; n[0]= bt.insertAsRoot("n0"); n[1]= bt.insertAsLC(n[0],"n1"); n[2]= bt.insertAsRC(n[0],"n2"); n[3]= bt.insertAsLC(n[1],"n3"); n[4]=bt.insertAsLC(n[2],"n4"); n[5]=bt.insertAsLC(n[4],"n5"); //測試根結點的高度 cout<<bt.getHight(n[2])<<endl; cout<<bt._root->height<<endl; return 0; }
運行結果以下:this
因爲每次插入新結點,都沒有對插入結點的父輩結點更新高度,因此bt樹的根結點的高度始終爲1.spa