二叉樹實例學習(四)——獲取節點的高度函數getHight()


樹T中所有節點深度的最大值稱為該樹的高度(height),實際上每個節點與其所有子節點都可以看做一顆樹,也就是說除了根結點,所有子結點都可以看做是一顆子樹,因此每個結點都有樹高。在本程序中約定,僅含單個結點的樹高為0,空樹高度為-1。據此,編寫getHight():

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

結點類定義代碼如下:

#ifndef BINNODE
#define BINNODE
#include <iostream>
//***************************************************************************************
///代碼5.2 , 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 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;
}

運行結果如下:

由於每次插入新結點,都沒有對插入結點的父輩結點更新高度,所以bt樹的根結點的高度始終為1.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM