PAT 1004 Counting Leaves (30 分)
思路分析
1、主要做的就是如何存储整个树的信息,要知道本题的树并非是常规的二叉树
2、可以考虑采用 struct node【maxsize】来整体记录
3、需要注意的是M行的父节点数字并非是按照顺序给出的,可以是乱序的状态
具体的代码展示
#include<iostream>
#include<malloc.h>
#include<vector>
using namespace std;
//首先是采用一个结构体来存储单行的信息,然后采用数组的形式来进行整体的存储
#define maxsize 101
struct Node
{
int father;//父节点
int level;//当前节点所在的层数
bool no_father;//布尔值表示是否当前节点是叶子节点
};
int sum_level[maxsize];//用来记录整体的每层的叶子节点的个数信息
Node node[maxsize];//整体的树的存储
int level_max=1;
vector<int>v;
int main()
{
//树中总的节点个数和非叶子节点个数
int N, M;
//由于在记录层数的时候会出现一个问题就是,M行的节点树不是顺序出现的,也就是说
int error = 1;
//有可能当前节点的父节点的信息还没有录入,其层数的信息仍然为初始值,从而到导致粗略的将当前节点的层数=父节点层数+1会出现问题
//这里error就是记录的是这种特殊情况,整体记录完毕之后,会对信息进行纠正,从而到正确的层数信息
cin >> N >> M;
//节点的初始化
for (int i = 1;i<=N;i++)
{
node[i].father = 0;
node[i].level = 0;
node[i].no_father = false;
sum_level[i] = 0;
}
node[1].level = 1;//将头节点的层数初始化为1
//M行信息的录入
for (int i = 1; i <= M; i++)
{
int parent;//输入一个父节点
int number;//输入一个当前节点的孩子节点树
int treenumber;//子树的节点树数字
cin >> parent;
cin >> number;
node[parent].no_father = true;//其父节点并非是叶子节点
for (int j = 1; j <= number; j++)
{
cin >> treenumber;
if (node[parent].level == 0)
{
node[treenumber].level = error * 100;
error++;
v.push_back(parent);//记录一下出现这种情况的父节点信息
}
else
{
node[treenumber].level = node[parent].level + 1;
}
node[treenumber].father = parent;
}
}
//对于整体的信息进行修正 (这一步可能有待改进)
for (int i =0;i<v.size();i++)
{
for (int j = 1; j <= N; j++)
{
if (node[j].level >= 100 * (i + 1) && node[j].level < 100 * (i + 2))
{
node[j].level = 1+node[v[i]].level + node[j].level%(100);
}
}
}
//看看有多少层
for (int i = 1; i <= N; i++)
{
if (node[i].level > level_max)
{
level_max = node[i].level;
}
}
//对于每层的非叶子节点信息进行统计
for (int i = 1; i <= N; i++)
{
if (node[i].no_father == false)
{
sum_level[node[i].level]++;
}
}
//对于空格的处理问题
cout << sum_level[1];
for (int i = 2; i <= level_max; i++)
{
cout << " "<<sum_level[i] ;
}
return 0;
}