菜鸡奋斗路03-树2 List Leaves

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 N1. 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
作者: 陈越
单位: 浙江大学
时间限制: 400ms
内存限制: 64MB
代码长度限制: 16KB


个人分析:题目要求根据输入建立一棵树,并从上到下,从左到右的输出叶结点的下标。同时,输出下标之间应以空格隔开,最后一个下标之后无空格。菜鸡第一想法:因知道最大N,采用结构数组表示树。树结点应有左右儿子下标,自身位置可由数组下标表示。由于需要从上到下,采用层序遍历,在遍历中判断当前结点是否是叶结点。在遇到第一个叶结点时,printf("%d"),并且时标记tag=1(初始化为0),后续每个叶结点在tag==1的情况下,均printf(" %d")。

等等,菜鸡在写代码的时候遇到了一个问题:树的结点下标在出队时并不能指示它本身的位置,如图:


解决完这个问题,其他的都是按部就班的写代码了。

代码如下:

#include<stdio.h>
#include<stdlib.h>
#define Maxsize 10
struct tree{
	int left;
	int right;
	int position;
}T[Maxsize];
typedef struct tree *Tree;

struct queue{
	tree data[Maxsize];
	int front;
	int rear;
}; 
typedef struct queue *Queue;

bool IsFull(Queue Q)
{
	if((Q->rear+1)%Maxsize==Q->front)
	{
//		printf("队列满\n");
		return false;
	}
	else
		return true; 
}

bool IsEmpty(Queue Q)
{
	if(Q->rear==Q->front)
	{
//		printf("队列空\n");
		return false;	
	}
	else
		return true;	
}

tree Delete(Queue Q)
{
	if(IsEmpty(Q)){
		tree t;
		t=Q->data[(Q->front+1)%Maxsize];
		Q->front=(Q->front+1)%Maxsize;
		return t;
	}

}
void Add(Queue Q,struct tree t)
{
	if(IsFull(Q)){
		Q->rear=(Q->rear+1)%Maxsize;
		Q->data[Q->rear]=t;
	}
}
int BuildTree()
{
	int number;
	char cl,cr;
	int check[Maxsize]={0};
	scanf("%d",&number);
	getchar();
	for(int i=0;i<number;i++)
	{
		scanf("%c %c",&cl,&cr);
		getchar();
		T[i].position=i;
		if(cl!='-'){
			T[i].left=cl-'0';
			check[T[i].left]=1;
		}else{
			T[i].left=-1;
		}
		if(cr!='-'){
			T[i].right=cr-'0';
			check[T[i].right]=1;
		}else{
			T[i].right=-1;
		}
		
	}
	for(int j=0;j<number;j++)
	{
		if(check[j]==0)
			return j;			
	}
}
void TravelTree(int root)
{
	Queue Q=(Queue)malloc(sizeof(queue));
	Q->front=Q->rear=0;
	tree t;
	Add(Q,T[root]);
	int tag=0; //标记输出数,从而符合输出格式 
	while(IsEmpty(Q)){
		t=Delete(Q);
		if(t.left==-1&&t.right==-1)
		{
			if(tag==0)
			{
				printf("%d",t.position);
				tag=1;
			}
			else
			{
				printf(" %d",t.position);
			 } 
		}
		if(t.left!=-1)
			Add(Q,T[t.left]);
		if(t.right!=-1)
			Add(Q,T[t.right]);
	}
}
int main()
{	
	//读树建树,返回头结点 
	int root=BuildTree();
	//建立队列层序遍历(即树的结点入队出队) 
	TravelTree(root);
	return 0;
 } 

测试结果:


总结:大体思路比较清晰,码量适中。让菜鸡重新温顾了一遍队列的定义及操作函数。



猜你喜欢

转载自blog.csdn.net/qq_41829562/article/details/80297132
今日推荐