zoukankan      html  css  js  c++  java
  • 1501 二叉树最大宽度和高度

    题目链接:http://codevs.cn/problem/1501/

    题目描述 Description

        给出一个二叉树,输出它的最大宽度和高度。

    输入描述 Input Description

    第一行一个整数n。

    下面n行每行有两个数,对于第i行的两个数,代表编号为i的节点所连接的两个左右儿子的编号。如果没有某个儿子为空,则为0。

    输出描述 Output Description

    输出共一行,输出二叉树的最大宽度和高度,用一个空格隔开。

    样例输入 Sample Input

    5

    2 3

    4 5

    0 0

    0 0

    0 0

    样例输出 Sample Output

    2 3

    数据范围及提示 Data Size & Hint

    n<16

    默认第一个是根节点

    以输入的次序为编号

    2-N+1行指的是这个节点的左孩子和右孩子

    注意:第二题有极端数据!

              1

              0 0

    思路:

    深度优先搜索二叉树,在搜索过程中每当进入第k层,则记录该层节点数的数组元素s[k]的值增加1.最后扫描数组s即可知道最大宽度。

    在深度搜索时,每当搜索的深度k大于历史最大深度时则记录目前为止搜索到的最大深度。

     1 #include<stdio.h>
     2 #include<string.h>
     3 int a[1000][2],s[1000];  //s[i]=x表示二叉树第i层有x个节点
     4 int i,n,maxHight,maxWide;   
     5 void dfs(int i,int k)  //i表示当前搜索的是第i个节点。k表示当前搜索到二叉树的第k层。
     6 {  
     7     s[k]=s[k]+1;//s[k]表示二叉树中第k层的节点数目 
     8     if(k>maxHight)  maxHight=k;  
     9     if(a[i][0]!=0)  dfs(a[i][0],k+1);
    10     if(a[i][1]!=0)  dfs(a[i][1],k+1);
    11 }
    12 int main()  
    13 {  
    14     scanf("%d",&n);  
    15     memset(a,0,sizeof(a));  
    16     memset(s,0,sizeof(s));  
    17     for(i=1;i<=n;i++)  
    18         scanf("%d%d",&a[i][0],&a[i][1]);  
    19     maxHight=0;
    20     dfs(1,1);
    21     maxWide=0;
    22     for(i=1;i<1000;i++)
    23         if(s[i]>maxWide)   maxWide=s[i];
    24     printf("%d %d",maxWide,maxHight);
    25     return 0;
    26 }

    代码二:广搜

     1 #include<iostream>
     2 #include<queue>
     3 #include<stdio.h>
     4 using namespace std;
     5 struct obj
     6 {
     7     int num,level;//某个节点的编号以及该节点所在的层级
     8 };
     9 
    10 int n,a[100][2]={0};//节点数n,顺序存储的二叉树
    11 queue<obj> q;//广搜的队列
    12 int s[100]={0};//s[i]=x表示二叉树第i层有x个节点
    13 int maxHight,maxWide;//最大深度、最大宽度
    14 
    15 int main()
    16 {
    17     int i,x,y;
    18     struct obj temp,temp2;
    19     freopen("data.in","r",stdin);
    20     scanf("%d",&n);
    21     for(i=1;i<=n;i++)
    22     {
    23         scanf("%d%d",&x,&y);
    24         a[i][0]=x;//节点i的左孩子
    25         a[i][1]=y;//节点i的右孩子
    26     }
    27 
    28     temp.num=1;
    29     temp.level=1;
    30     q.push(temp);
    31     s[1]=1;
    32     maxHight=1;
    33     while(!q.empty())
    34     {
    35         temp=q.front(); q.pop();
    36         if(a[temp.num][0]!=0)//队头的左孩子节点入队
    37         {
    38             temp2.num=a[temp.num][0];
    39             temp2.level=temp.level+1;
    40             q.push(temp2);
    41             if(temp2.level>maxHight) maxHight=temp2.level;
    42             s[temp2.level]++;
    43         }
    44         if(a[temp.num][1]!=0)//队头的右孩子节点入队
    45         {
    46             temp2.num=a[temp.num][1];
    47             temp2.level=temp.level+1;
    48             q.push(temp2);
    49             if(temp2.level>maxHight) maxHight=temp2.level;
    50             s[temp2.level]++;
    51         }
    52     }
    53     maxWide=-1;
    54     for(i=1;i<=n;i++)
    55     {
    56         if(s[i]>maxWide) maxWide=s[i];
    57     }
    58     printf("%d %d
    ",maxWide,maxHight);
    59     return 0;
    60 }

     黎芷淇的代码:

     1 #include <iostream>
     2 using namespace std;
     3 typedef struct
     4 {
     5     int lc,rc;//该结点左右孩子结点的编号
     6     int floor;//该结点所在层级
     7 }node;
     8 int main(int argc, char *argv[])
     9 {
    10     int n,i,j,x,y;
    11     int max=0,h=0,sum;
    12     node tree[20];
    13     cin>>n;
    14     tree[1].floor=1;
    15     for(i=1;i<=n;i++)
    16     {
    17         cin>>x>>y;
    18         tree[i].lc=x;tree[i].rc=y;
    19         tree[x].floor=tree[i].floor+1;tree[y].floor=tree[i].floor+1;
    20     }
    21     for(i=1;i<=n;i++)
    22     {
    23         if(tree[i].floor>h)h=tree[i].floor;
    24     }
    25     for(i=1;i<=h;i++)
    26     {
    27         sum=0;
    28         for(j=1;j<=n;j++)
    29         {
    30             if(tree[j].floor==i)sum++;
    31         }
    32         if(sum>max)max=sum;
    33     }
    34     cout<<max<<" "<<h;
    35     return 0;
    36 }

    何泓历的代码:

     1 #include <stdio.h>
     2 int main()
     3 {
     4     int a[17][2]={0},n,i,b[17]={0},p1,p2,maxl=0,maxh=0;
     5     //a[i][0]表示i节点的父亲,a[i][1]表示i节点的层,b[i]表示第i层节点数 
     6     //maxl表示最大宽度,maxh表示最大深度 
     7     scanf("%d",&n);
     8     for(i=1;i<=n;i++)
     9     {
    10         scanf("%d%d",&p1,&p2);
    11         a[p1][0]=a[p2][0]=i;
    12         a[p1][1]=a[p2][1]=a[i][1]+1;
    13         maxl=maxl<++b[a[i][1]]?b[a[i][1]]:maxl;
    14         maxh=maxh<a[i][1]?a[i][1]:maxh;
    15     }
    16     printf("%d %d
    ",maxl,maxh+1);
    17     return 0;
    18 }

    黄晓涛的代码:

     1 #include <stdio.h>
     2 int wide[100],a[100],n,x,y,maxdeep=0,maxwide=0;
     3 int main(int argc, char *argv[])
     4 {
     5     a[1]=1;
     6     wide[1]=1;
     7     maxdeep=1;
     8     scanf("%d",&n);
     9     for(int i=1;i<=n;i++)
    10     {
    11         scanf("%d %d",&x,&y);
    12         if(x!=0)
    13         {
    14             a[x]=a[i]+1;//a[x]表示x节点所在的层数。它等于父节点层数加1.
    15             wide[a[x]]++;//wide[i]表示节点i所在层的宽度
    16         }
    17         if(y!=0)
    18         {
    19             a[y]=a[i]+1;
    20             wide[a[y]]++;
    21         }
    22         if(a[x]>maxdeep)
    23         {
    24             maxdeep=a[x];
    25         }
    26         else if(a[y]>maxdeep)
    27         {
    28             maxdeep=a[y];
    29         }    
    30     }
    31     for(int i=1;i<=n;i++)
    32     {
    33         if(wide[i]>maxwide)
    34         maxwide=wide[i];
    35     }
    36     printf("%d %d
    ",maxwide,maxdeep);
    37     return 0;
    38 }
  • 相关阅读:
    金斗云提醒用法说明
    金斗云提醒软件的原理
    缓存雪崩问题,缓存击穿问题,缓存一致性问题(内存+数据库)
    Spring的ApplicationEvent实现
    区块链技术--区块链的生成和链接
    区块链技术--比特币交易的锁定和解锁
    区块链技术--密码学
    区块链技术--比特币
    jedis中scan的实现
    KafkaManager对offset的两种管理方式
  • 原文地址:https://www.cnblogs.com/huashanqingzhu/p/7183746.html
Copyright © 2011-2022 走看看