给出一个二叉树,输出它的最大宽度和高度.
二叉树最大宽度与高度
题目描述:给出一个二叉树,输出它的最大宽度和高度.
输入描述:第一行一个整数n.下面n行每行有两个数,对于第i行的两个数,代表编号为i的节点所连接的两个左右儿子的编号.如果没有某个儿子为空,则为0.
输出描述:输出一共三行,分别为前序遍历,中序遍历和后序遍历.编号之间用空格隔开.
说明:默认结点1是根节点,根节点的高度为1.
大概思路:高度就是最下方结点的层数,宽度就是层结点数最多层的结点数.
以这棵树为例,高度就是最下方结点(绿色结点)的层数,也就是4;宽度就是层结点数最多层(第4层)的结点数.
第一步:用一个多维数组tree[21][4]来储存这棵树,tree[n][0]为结点n的左子树,[n][1]为结点n的右子树,[n][2]为结点n的父亲,[n][3]为结点n所在层数.
根据输入描述,第i个结点的左儿子和右儿子都是在第i行读入的,当读入第i行时,如果有左儿子就把左儿子的父亲设为i,右儿子同理.
第二步:把tree[1][3]设为1,因为默认结点1高度为1.因为每个非根结点所在的层数是它父亲所在层数+1,代码表示:tree[i][3]=tree[tree[i][2]][3]+1;
递推算出每1层的层数,算出层数的同时直接寻找最大值.
第三步:在第二步执行过程中,如果碰到一个结点属于第i层,那么layer[i]+1(初始每个元素都为0),到第二步执行完成,就寻找layer中的最大值,最大值的下标就是宽度.
AC代码如下:
1 #include <iostream>
2 #include <cstring>
3
4 using namespace std;
5
6 int tree[21][4];/* 二维数组tree,储存了输入的二叉树 */
7 /* tree[n][0]为结点n的左子树,[n][1]为结点n的右子树,[n][2]为结点n的父亲,[n][3]为结点n所在层数 */
8 int layer[20];/* 层数数组,layer[i]就是第i层的结点数,也就是第i层的宽度 */
9 int findmax()/* 找到layer中的最大值,也就是也就是最大宽度 */
10 {
11 int maxmium = -1;
12 for (int i = 1; i < sizeof(layer)/sizeof(layer[0]); i++)
13 {
14 if (layer[i]>maxmium)
15 {
16 maxmium=layer[i];
17 }
18 }
19 return maxmium;
20 }
21 int main()
22 {
23 int n,depth=1;
24 cin >> n;
25 memset(layer,sizeof(layer),0);
26 for (int i = 1; i <= n; i++)
27 {
28 cin >> tree[i][0] >> tree[i][1];/* 读入二叉树 */
29 if (tree[i][0] != 0)
30 {
31 tree[tree[i][0]][2] = i;/* 设置父亲 */
32 }
33 if (tree[i][1] != 0)
34 {
35 tree[tree[i][1]][2] = i;/* 设置父亲 */
36 }
37 }
38 tree[1][3] = 1;/* 根结点的层数默认为1 */
39 layer[1]=1;/* 第一层的宽度一定为1 */
40 for (int i = 2; i <= n; i++)
41 {
42 tree[i][3] = tree[tree[i][2]][3] + 1;/* 第i个结点的层数是它父亲的层数+1,递推 */
43 layer[tree[i][3]]++;/* 第i个结点所属的层数+1,统计每层的节点数 */
44 if (tree[i][3] > depth)
45 {
46 depth = tree[i][3];/* 设置层数的同时直接比较高度(高度即层数) */
47 }
48 }
49 cout << findmax() << ' ' << depth;/* 输出 */
50 return 0;
51 }