• 牛客网在线编程题——树的高度(2)


    题目描述

    现在有一棵合法的二叉树,树的节点都是用数字表示,现在给定这棵树上所有的父子关系,求这棵树的高度

    输入描述:

    输入的第一行表示节点的个数n(1 ≤ n ≤ 1000,节点的编号为0到n-1)组成,
    下面是n-1行,每行有两个整数,第一个数表示父节点的编号,第二个数表示子节点的编号

    输出描述:

    输出树的高度,为一个整数
    示例1

    输入

    5
    0 1
    0 2
    1 3
    1 4
    

    输出

    3


    两种解题思路
    1、用输入数据构造二叉树,根据二叉树再求树的高度;

    2、根据一个节点只有一个父节点的思路求解(需要考虑非法二叉树的情况)。
    第一种思路的解题代码(参考代码:https://blog.csdn.net/qq_40269087/article/details/80443682):
    #include<iostream>
    #include<malloc.h>
    using namespace std;
      
    typedef struct BiTreeNode//定义节点结构
    {
        int data;
        struct BiTreeNode *lchild,*rchild;
    }BiTreeNode,*BiTree;
      
    void CreateBiTree(BiTree T, int x, int y)//构造二叉树
    {
        BiTree t;
        if(T)
        {
            if(T->data==x){
                if(T->lchild==NULL)
                {
                    t=(BiTree)malloc(sizeof(BiTreeNode));
                    t->data=y;
                    t->lchild=NULL;
                    t->rchild=NULL;
                    T->lchild=t;
                }else if(T->rchild==NULL)
                {
                    t=(BiTree)malloc(sizeof(BiTreeNode));
                    t->data=y;
                    t->lchild=NULL;
                    t->rchild=NULL;
                    T->rchild=t;
                }
            }else
            {
                CreateBiTree(T->lchild,x,y);
                CreateBiTree(T->rchild,x,y);
            }
        }
    }
    int Depth(BiTree T)//求树的深度
    {
        if(T==NULL){
            return 0;
        }else{
            int m=Depth(T->lchild);
            int n=Depth(T->rchild);
            if(m>n){
                return m+1;
            }else{
                return n+1;
            }
        }
    }
      
    int main(){
        int n,a,b;
        cin>>n;
        BiTree root;
        root=(BiTree)malloc(sizeof(BiTreeNode));
        root->data=0;
        root->lchild=NULL;
        root->rchild=NULL;
        for(int i=0;i<n-1;i++){
            cin>>a>>b;
            CreateBiTree(root,a,b);
        }
        cout<<Depth(root)<<endl;
        return 0;
    }

    值得学习的点:1、构造二叉树的关键点①找到待插入节点的父节点②确定是插入到左子树还是右子树。

           2、构造二叉树和求解二叉树的深度都是采用递归的方法,思想可以借鉴,但是需要注意递归算法的通病:比较耗时。

           3、输入数据时,采用二叉树存储数据。值得思考的问题是在解答问题先,需要先考虑好使用什么数据结构来存储输入数据,这样会促使自己去把具体问题,与数据结构相结合,有助于加快解题。

    第二种解题思路的代码(参考代码:https://www.nowcoder.com/discuss/11934?type=1&pos=&page=1 评论中的第12楼):

    #include<iostream>
    #include<vector>
    using namespace std;
    int main()
    {
        int n,a,b;
        cin>>n;
        int nodeindex[n];
        bool flag[n];//节点有效性标志
        for(int i=0;i<n;i++)//初始化
        {
            nodeindex[i]=-1;
            flag[i]=true;
        }
        for(int i=0;i<n-1;i++)
        {
            cin>>a>>b;
            int count=0;
            for(int j=0;j<n;j++)
            {
                if(nodeindex[j]==a)
                {
                    count++;
                }
            }
            if(count<2)//合法二叉树
            {
                if(flag[a]==true)
                {
                    nodeindex[b]=a;//数组中的下标为子节点,值为父节点
                }else//但是父节点无效,所以其对应的子节点也无效
                {
                    flag[b]=false;
                }
            }else//同一个父节点上的子节点数目大于2,为非法二叉树,将多余子节点置为无效节点
            {
                flag[b]=false;
            }
        }
        int max=0;
        int count=0;
        for(int i=0;i<n;i++)//遍历所有的节点,以该节点出发,求对应的树的高度
        {
            if(flag[i])//筛除掉无效节点
            {
                int cur=i;
                while(cur!=-1)
                {
                    cur=nodeindex[cur];
                    count++;
                }
                if(count>max)
                {
                    max=count;
                }
                count=0;
            }
        }
        cout<<max;
        return 0;
    }

    值得学习的点:1、所有的节点都只对应了唯一一个父节点,利用这种思路可以避开根据输入数据生成二叉树的步骤;

           2、需要排除非法二叉树的情况,就是一个父节点下有超过2个的子节点,选用合适的标志,排除非法情况。

    两种思路的比较:

    1、个人更加赞同使用思路1中的方法,因为该方法更加的传统,使用性更广泛,关键是在短的时间里很容易想到;

    2、方法二就显得十分的巧妙,思路短时间难以形成,并且需要自己去排除非法二叉树的情况(这也是题目比较坑的地方,很多参考代码都没有将这点考虑进去,最终只能达到50%的通过案例)。






  • 相关阅读:
    cocos creator 场景如何透明,多个canvas层级显示
    c/c++导出lua绑定
    c++自动导出lua绑定
    获取Sprite上某一个点的透明度
    cocos2d-x lua中实现异步加载纹理
    keystore找回密码
    xcode 制作静态库文件(.a)
    Ajax学习笔记之一----------第一个Ajax Demo[转载]
    lua调用java java调用lua[转载]
    WPF中模板选择和DataContext的一些使用
  • 原文地址:https://www.cnblogs.com/lipanDL/p/10009208.html
Copyright © 2020-2023  润新知