译文:
给定一棵树,你应该按照从上到下、从左到右的顺序列出所有的叶节点。
输入:
每个输入文件包含一个测试用例。对于每种情况,第一行给出一个正整数N(≤10),这是树中的节点总数——因此节点编号从0到N−1。然后N行,每一行对应一个节点,并给出该节点的左子节点和右子节点的索引。如果子节点不存在,则在该位置放置一个“-”。任何一对子对象都用一个空格隔开。
输出:
对于每个测试用例,按照从上到下和从左到右的顺序在一行中打印所有叶子的索引。相邻数字之间必须有一个空格,行尾不能有多余的空格。
样例输入:
8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6
样例输出:
4 1 5
分析:给出你每个结点(结点从0-n-1)的左右孩子,然后让你从上到下,从左到右输出叶子结点。
首先找到根节点,再用队列,用结构体存储结点的左右孩子,以便后面队列找叶结点。
代码:
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int N = 50;
struct NODE{
int lf=-1,rf=-1;
}node[N];
int vis[N];//找根节点的数组。
int islea[N];//判断是否是叶结点。
vector<int>a;//存储叶结点的数组。
int main(){
queue<int> q;//队列需要遍历的节点;
int n,root = 0;
scanf("%d",&n);
memset(vis,0,sizeof vis);
for(int i=0;i<n;i++){
char l,r;
cin >>l>>r;
if(l == '-' && r == '-') islea[i] = 1;
if(l != '-'){
vis[l - '0'] ++;
node[i].lf = l - '0';
}
if(r != '-'){
vis[r - '0'] ++;
node[i].rf = r - '0';
}
}
for(int i=0;i<n;i++) if(!vis[i]) root = i;//找到根结点;
q.push(root);
while(!q.empty()){
int t = q.front();
q.pop();
if(islea[t] == 1) a.push_back(t);//判断当前节点是否为叶节点
if(node[t].lf != -1) q.push(node[t].lf);
if(node[t].rf != -1) q.push(node[t].rf);
}
for(int i=0;i<a.size();i++){
cout << a[i];
if(i!=a.size() - 1) cout << " ";
}
return 0;
}