给定一棵树,您应该按照从上到下、从左到右的顺序列出所有叶子。
每个输入文件都包含一个测试用例。对于每种情况,第一行都给出一个正整数N(<=10),这是树中节点的总数 -- 因此节点的编号从 0 到N-1.然后N行紧随其后,每行对应一个节点,并给出节点的左右子节点的索引。如果孩子不存在,则会在该位置放置一个“-”。任何一对子项之间都用空格隔开。
对于每个测试用例,按照自上而下和从左到右的顺序在一行中打印所有叶子的索引。任何相邻数字之间必须只有一个空格,并且行尾不能有多余的空格。
8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6
4 1 5
这里附上英文原文,避免题目歧义。
思路如注释所示,可通过所有测试点。
- #include
- using namespace std;
- int main(){
- int vis[10]={0},tree[10][2]; //vis[]检查数组,用来找根节点
- int N,Root; //tree[]用来存储树的结点信息
- cin>>N;
- for(int i = 0;i < N;i++){
- tree[i][0] = -1;
- tree[i][1] = -1;
- }
- for(int i = 0;i < N;i++){
- char a,b;
- cin>>a>>b;
- a != '-' ? vis[a-'0'] = 1,tree[i][0] = a-'0':vis[a] = 0; //记录一个结点是否为子结点
- b != '-' ? vis[b-'0'] = 1,tree[i][1] = b-'0':vis[b] = 0;
- }
-
- for(int i = 0;i < N;i++){
- if(vis[i]==0) Root = i; //不为任意结点的子结点的结点即为根结点
- }
- int front = -1,rear = -1,queue[N]={0},num=0;
- queue[rear++] = Root;
- while(front != rear){
- num++; //已经查找过的结点数量
- int i = queue[front++];
- if(tree[i][0]!=-1) queue[rear++] = tree[i][0];
- if(tree[i][1]!=-1) queue[rear++] = tree[i][1];
- if(tree[i][0] == -1 && tree[i][1] == -1){
- cout<
- if(num!=N) cout<<' '; //因为遍历到最后一个结点的同时,这个结点也应该是最后一个叶子
- } //结点,所以不在它后面加空格
- }
- return 0;
- }
思路:
这道题是树的遍历中比较经典的一道题,题目意思很清楚,传统做法应该是构造一个结构体,但是像我这么懒的人看了结点数最多只有10个,我就直接用二维数组做了,初学者可以把这个做法作为传统做法的前导,关于树的一些传统的更规范的操作我也有写一篇,感兴趣朋友可以转去
核心思想还是BFS,逐层遍历每个结点,输出没有子结点的结点,这里用队列来存储比较方便。输出优先级是层>左>右。