【PAT】3-2 List Leaves【树、队列、遍历】
题目:http://www.patest.cn/contests/mooc-ds/03-%E6%A0%912
题意:给出树的一些结点,每个结点的两个值分别表示左儿子和右儿子,所以根节点肯定不会出现在上面的数据中,因为根节点不是其它任何节点的儿子。最后的要求是按照层序遍历的方式输出叶子结点。
思路:先建树,建树的同时寻找根结点,具体办法是用一个标记数组,遍历结点的时候同时把结点标记成ture,最后没有被标记到的结点就是根结点了。建完树之后层序遍历输出叶子结点就行了。
代码里一些需要注意的地方,构造树的时候,我们把用来构造结点的结构体当成C++的类,然后用构造函数进行赋值(赋值一个与题意里面的结点相悖的特殊值),这样遍历之后,如果结点仍然保持那个特殊值不变的话说明它没有左右儿子就是叶子结点了,打印即可。
AC代码:
#include <iostream> #include <algorithm> #include <cstdlib> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <ctime> #include <set> #include <queue> using namespace std; #define read() freopen("data.in", "r", stdin) #define write() freopen("data.out", "w", stdout) #define clr( a , x ) memset ( a , x , sizeof a ) #define cpy( a , x ) memcpy ( a , x , sizeof a ) #define _max(a,b) ((a>b)?(a):(b)) #define _min(a,b) ((a<b)?(a):(b)) #define LL long long struct Node { int leftchild; int rightchild; Node(){ leftchild = -233; rightchild = -233; } }; Node node[50]; bool root[50]; queue<int> q; int flag = 0; void Traversal(int a) { q.push(a); while(!q.empty()) { int j = q.front(); q.pop(); if (node[j].leftchild == -233 && node[j].rightchild == -233) { if (flag == 0) { printf("%d",j); flag = 1; }else { printf(" %d",j); } } if (node[j].leftchild != -233) { q.push(node[j].leftchild); } if (node[j].rightchild != -233) { q.push(node[j].rightchild); } } printf("\n"); } int main() { //read(); clr(root,false); char left,right; int n; cin>>n; getchar(); for (int i = 0; i < n; ++i) { scanf("%c %c",&left,&right); getchar(); if (isdigit(left)) { node[i].leftchild = left - '0'; root[node[i].leftchild] = true; } if (isdigit(right)) { node[i].rightchild = right - '0'; root[node[i].rightchild] = true; } } for (int i = 0; i < n; ++i) { if (root[i] == false) { Traversal(i); break; } } return 0; }