先看一下题目
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
题目如上,下面我们来分析一下:
给定一棵树,节点数由第一行输入决定。下边每一行读进去两个数,分别是以输入行数为下标的节点(0~N-1)的左儿子和右儿子,“-”代表无儿子,按从上到下从左到右的顺序输出叶节点。仔细一想,输出不就是层序遍历吗?!所以我们可以用队列。
所以解题思路是这样的:创建树,找到其根节点,遍历输出。
首先我们看一下main函数
int root,N;
int main(){
scanf("%d",&N);
root=CreateTree(N);//创建树
traversal(root);//层序遍历输出叶节点
return 0;
}
然后我们写一下树结构和存放树节点下标的队列结构
//根下标以及读入最大节点数
struct TreeNode{
int left,right;
}Tree[10];//最大节点数为10
struct queue{
int *data;
int front,rear;
}
因为CreateTree()函数需要读入一棵树且要返回此树的节点,所以我们还需要一个check数组来检查节点的位置。先将check数组全部置零,通过读入左儿子有儿子,当左儿子或右儿子不为‘-’时,将check数组对应的下标置为1,最后遍历check数组,判断若为1则赋给root返回,代码如下:
int CreateTree(int n){
char l,r;
int i;
int check[n];
for(i=0;i<n;i++)
check[i]=0;
for(i=0;i<n;i++)
{
scanf("%c %c",&l,&r);
getchar();//吸收掉回车,很重要!!!
if(l!='-')
{
Tree[i].left=l-'0'; //l减‘0’即为整数
check[i]=1;
}
else Tree[i].left=-1; //若不存在左孩子,则为-1
if(r!='-')
{
Tree[i].right=r-'0';
check[i]=1;
}
else Tree[i].right=-1;
}
for(i=0;i<n;i++)
{
if(!check[i])
root=i; //若不为0,根节点为i;
}
return root;
}
下面我们创建队列有关的操作
Queue CreateQueue(){
Queue q=(Queue)malloc(sizeof(struct queue));
q->index=(int*)malloc(8*sizeof(int));
q->front=q->rear=-1;
return q;
}
bool isEmpty(Queue q)
{
return(q->front==q->rear);
}
void add(Queue q,int x)
{
if((q->rear+1)%10==q->front)
{
return;
}
else
{
q->rear=(q->rear+1)%8;
q->index[q->rear]=x;
}
}
int pop(Queue q){
if(q->front==q->rear)
{
return -1;
}
else
{
q->front=(q->front+1)%8;
return q->index[q->front];
}
}
下边构建层序遍历函数,代码如下:
void Traversal(int root1)
{
int temp;//用来储存出队节点下标的临时变量
Queue q=CreateQueue();
add(q,root1);
while(!isEmpty(q)) //若队列不空
{
temp=pop(q);
if(Tree[temp].left!='-'&&Tree[temp].right!='-')
{
add(q,Tree[Tree[temp].left]);
add(q,Tree[Tree[temp].right]);
}
else if(Tree[temp].left!='-'&&Tree[temp].right=='-')
{
add(q,Tree[Tree[temp].left]);
}
else if(Tree[temp].left=='-'&&Tree[temp].right!='-')
{
add(q,Tree[Tree[temp].right]);
}
else
printf("%d",temp);//输出叶节点
}
}
输出结果如下:
下边附上完整代码:
#include <stdio.h>
#include <stdlib.h>
void traversal(int root2);
typedef enum {flase=0,true=1} bool;
int CreateTree(int N);
struct queue{
int * index;
int front,rear;
};
typedef struct queue* Queue;
struct treeNode{
int left,right;
}tree[8];
int N,root;
int main(){
scanf("%d",&N);
root=CreateTree(N);
traversal(root);
return 0;
}
int CreateTree(int n){
char l,r;
int i;
int check[n];
for(i=0;i<n;i++)
check[i]=0;
for(i=0;i<n;i++)
{
getchar(); //很重要,首先把读入N后的回车吸掉,然后吸收每行末尾的换行符
scanf("%c %c",&l,&r);
if(l!='-')
{
tree[i].left=l-'0';
check[tree[i].left]=1;
}
else
tree[i].left=-1;
if(r!='-')
{
tree[i].right=r-'0';
check[tree[i].right]=1;
}
else
tree[i].right=-1;
}
for(i=0;i<n;i++)
{
if(check[i]==0)
{
root=i;
break;
}
}
return root;
}
//创建队列
Queue CreateQueue(){
Queue q=(Queue)malloc(sizeof(struct queue));
q->index=(int*)malloc(8*sizeof(int));
q->front=q->rear=-1;
return q;
}
bool isEmpty(Queue q)
{
return(q->front==q->rear);
}
void add(Queue q,int x)
{
if((q->rear+1)%10==q->front)
{
return;
}
else
{
q->rear=(q->rear+1)%8;
q->index[q->rear]=x;
}
}
int pop(Queue q){
if(q->front==q->rear)
{
return -1;
}
else
{
q->front=(q->front+1)%8;
return q->index[q->front];
}
}
void traversal(int root2)
{
int temp;//存放出队节点下标的临时变量
Queue q=CreateQueue();
add(q,root2);
// while(q->front!=q->rear)
while(!isEmpty(q))
{
temp=pop(q);
if(tree[temp].left!=-1&&tree[temp].right!=-1)
{
add(q,tree[temp].left);
add(q,tree[temp].right);
}
else if(tree[temp].left!=-1&&tree[temp].right==-1)
add(q,tree[temp].left);
else if(tree[temp].left==-1&&tree[temp].right!=-1)
add(q,tree[temp].right);
else
{
printf("%d ",temp);
}
}
}