Given a tree, you are supposed to list all the leaves in the order of top down, and left to right.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤10) which is the total number of nodes in the tree – and hence the nodes are numbered from 0 to N−1. Then N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a “-” will be put at the position. Any pair of children are separated by a space.
Output Specification:
For each test case, print in one line all the leaves’ indices in the order of top down, and left to right. There must be exactly one space between any adjacent numbers, and no extra space at the end of the line.
Sample Input:
8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6
Sample Output:
4 1 5
参考代码:
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MAXSIZE 10
/*定义队列*/
typedef struct QNode *queue;
struct QNode{
int data[MAXSIZE];
int front;
int rear;
};
/*定义树节点*/
typedef struct TNode{
int data;
int left;
int right;
}ArrayList[MAXSIZE];
queue CreateQueue(); //创建队列
bool IsEmpty(queue q); //队列是否为空
void AddQ(queue q,int x); //入队
int DeleteQ(queue q); //出队
int main()
{
int i,N,root;//root表示树的根节点索引
scanf("%d",&N);
int check[MAXSIZE]={0};
ArrayList T;
char l,r;
getchar(); //读入换行符
for(i=0;i<N;i++)
{
T[i].data=i;
scanf("%c %c",&l,&r); //读入该结点左右孩子
getchar(); //读入换行符
T[i].left=(l=='-'?-1:l-'0');//转换为整型保存,不存在用-1表示
T[i].right=(r=='-'?-1:r-'0');
if(T[i].left>=0) //如果左孩子存在
check[T[i].left]=1;
if(T[i].right>=0) //如果右孩子存在
check[T[i].right]=1;
}
for(i=0;i<N;i++) //找根结点
{
if(check[i]==0)
root=i;
}
queue q;
int nodeData,flag=0;//flag用来格式输出
q=CreateQueue();
AddQ(q,root);
while(!IsEmpty(q))
{
nodeData=DeleteQ(q);
if(T[nodeData].left==-1&&T[nodeData].right==-1)//如果左右孩子都没有
{
if(!flag) flag=1;
else printf(" ");
printf("%d",nodeData);
}
if(T[nodeData].left>=0)
AddQ(q,T[nodeData].left);
if(T[nodeData].right>=0)
AddQ(q,T[nodeData].right);
}
return 0;
}
queue CreateQueue()
{
queue q=(queue)malloc(sizeof(struct QNode));
q->front=q->rear=0;
return q;
}
bool IsEmpty(queue q)
{
return (q->front==q->rear);
}
void AddQ(queue q,int x)
{
q->rear=(q->rear+1)%MAXSIZE;
q->data[q->rear]=x;
}
int DeleteQ(queue q)
{
q->front=(q->front+1)%MAXSIZE;
return q->data[q->front];
}
思路:
- 题目最后要求输出从上到下,从左到右树的叶子结点,这里我们很容易看出用层次遍历,这里我们需要用个队列去实现;
- 题目要求输入N个数,每行对应一个结点(索引对应结点数,第一行输入的结点就是0,第二行输入的结点就是1),每行输入左右孩子索引。这里我们用个结构数组用来保存树的结点(数组中结点是随机存放的),如果我们层次遍历这个树,我们就需要找到这个树的根结点,从而根据左右孩子层次遍历完整个树。
- 如何找到树的根结点?我们可以从左右孩子里查找,如果这个数没有出现在左右孩子索引中,那么这个数就是树的根结点数。这里代码中我们定义了一个check[ ]数组,用来保存该结点数是否出现在左右孩子中。