List Leaves (25分)

原题描述如下:

List Leaves (25分)
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(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
题目大意如下:
给定正整数N(N<=10),然后输入N个节点,每个节点的数字分别代表左子树、右子树,如果该节点为空则用字符’-‘代表。输出每个叶子节点,按照从上到下,从左到右的顺序。
题目思路,先找出根节点,然后层序遍历该树,如果遍历的节点的左子树与右子树都为空则打印该节点。
代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define Null -1 
#define MAX 10
typedef struct TNode{
    int Left;
    int Right;
}Tree; 
typedef struct{
    int rear;
    int front;
    int Data[2*MAX];
}Queue;
int IsFull(Queue *);
int IsEmpty(Queue *);
int BuildTree(Tree *t,int); 
Queue *CreateQueue();
void AddQueue(Queue *,int);
int DeleteQueue(Queue *);
void LevelOrderTraversal(Tree *,int );
int main()
{

    int N;
    scanf("%d\n",&N);
    Tree T[N];
    int root=BuildTree(T,N);
// 测试打印根节点
// printf("%d",root);
// 层序遍历该树
    LevelOrderTraversal(T,root);
    return 0;
}
Queue *CreatQueue()
{
    Queue *PtrQ=(Queue *)malloc(sizeof(Queue));
    PtrQ->rear=PtrQ->front=Null;
    return PtrQ;
}
void AddQueue(Queue *PtrQ,int item) 
{
    if(!IsFull(PtrQ))
    {
        PtrQ->rear=(PtrQ->rear+1)%MAX;
        PtrQ->Data[PtrQ->rear]=item;
    }
}
int DeleteQueue(Queue *PtrQ)
{
    if(!IsEmpty(PtrQ))
    {
        PtrQ->front=(PtrQ->front+1)%MAX;
        return PtrQ->Data[PtrQ->front];
    }else
    {
        return Null;
    }
}
int IsFull(Queue *PtrQ)
{
    int tag=0;
    if((PtrQ->rear+1)%MAX==PtrQ->front)
    {
        tag=1;
    }
    return tag;
}
int IsEmpty(Queue *PtrQ)
{
    int tag=0;
    if(PtrQ->front==PtrQ->rear)
    {
        tag=1;
    }
    return tag;
}
//创建树
int BuildTree(Tree *t,int N)
{
    int i;
// 用于检查哪个节点未被访问过,该节点则为根节点
    int check[N];
    int Root;
// 初识化为0,访问过标记为1
    memset(check,0,sizeof(check));
    char L,R;
    for(i=0;i<N;i++)
    {
        scanf("%c %c\n",&L,&R);
// 判断节点是否为空,如果为空则用Null(-1)代替。
        if(L!='-')
        {
            t[i].Left=L-'0';
            check[t[i].Left]=1;
        }
        else
        {
            t[i].Left=Null;
        }
        if(R!='-')
        {
            t[i].Right=R-'0';
            check[t[i].Right]=1;
        }
        else
        {
            t[i].Right=Null;
        }
    }
// 遍历check数组,如果某个节点未被访问过,那么该节点则为根节点
    for(i=0;i<N;i++)
    {
        if(check[i]!=1)
        {
            Root=i;
        }
    }
// 返回根节点
    return Root;
}
//层序遍历
void LevelOrderTraversal(Tree *T,int t)
{
    int tag=0;
    Queue *Q=CreatQueue(MAX);
    if (T[t].Left!=Null&&T[t].Right!=Null)
    {
// 根节点入队
        AddQueue(Q,t);
        while (!IsEmpty(Q) )
        {
// 出队
            int Data=DeleteQueue(Q);
// 判断该节点的左子树、右子树是否都为空,是则打印
            if(T[Data].Left==Null&&T[Data].Right==Null)
            {
// 用于标记空格输出情况
// 可将输出情况理解为(空格,输出,空格,输出...)第
// 一个不用输出空格其它需要
                if(!tag)
                {
                    printf("%d",Data);
                    tag=1;
                }
                else
                {
                    printf(" %d",Data);
                }
            }
// 将节点的左子树入队
            if (T[Data].Left!=Null)
            {
                AddQueue(Q,T[Data].Left);
            }
// 将节点右子树入队
            if (T[Data].Right!=Null)
            {
                AddQueue(Q,T[Data].Right);
            }
        }
    }
    else if(T[t].Left==Null&&T[t].Right==Null)
    {
        printf("%d",t);
    }
}
点赞