zoukankan      html  css  js  c++  java
  • 二叉树实例学习(四)——获取节点的高度函数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.

  • 相关阅读:
    python 线程队列PriorityQueue(优先队列)(37)
    python 线程队列LifoQueue-LIFO(36)
    python线程队列Queue-FIFO(35)
    python线程障碍对象Barrier(34)
    关于mybatis 在C#.Net中批量增,删,改
    c#如实现将一个数字转化为其他进制字符串输出
    Tostring(); 括号中的参数 格式化字符串
    前端笔记之HTML5&CSS3(上)新特性&音频视频&本地存储&自定义属性
    前端笔记之jQuery(下)事件&节点操作&净位置&拖拽&页面卷动值&遍历JSON
    前端笔记之jQuery(上)加载函数的区别&对象&操作HTML/CSS&动画&选择器
  • 原文地址:https://www.cnblogs.com/phoenixdsg/p/9770919.html
Copyright © 2011-2022 走看看