中国大学MOOC-陈越、何钦铭-数据结构-2021春:03-树2 List Leaves (25 分)(笔记)

题意如下:
03-2 列表叶 (25)
如果有一棵树,你应该按自上而下、从左到右排列所有叶子。

输入规范:
每个输入文件包含一个测试案例。对于每个案例,第一行给出一个正整数N (10)这是树上的节点总数-因此节点编号从0到N−1.然后N行跟随,每个对应于一个节点,并给出节点的左右子的指数。如果孩子不存在,将放置一个"-"的位置。任何一对孩子都被一个空间隔开。

输出规格:
对于每个测试案例,以自上而下、从左到右的顺序以一行打印所有叶子的指数。任何相邻数字之间必须正好有一个空格,**并且行尾没有额外的空格**。

示例输入:
8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6
样本输出:
4 1 5

注意:输入的每一行是按照从0号结点开始到N-1号结点的左右孩子

//思路:首先定义一个树结点的数组结构体,将二维树转换成一维数组的形式进行存储,该结构体定义为数组形式,结构体数组的下标对应着该结点编号,该结构体中存储着该结点的左右孩子的编号。然后进行输入。因为要从上到下,从左到右输出叶子节点,所以采用中序遍历的方法实现输出,这个时候就要定义队列进行存储和遍历树。
#include<stdio.h>
struct TNode{//定义树结点
    int left;//左孩子
    int right;//右孩子
}T[10];//因为结点最多有十个
int main(){
    int N,i=0,book[10]={0},flag=0;//book用于查找头结点,flag用于判断是否是第一个结点用来输出空格
    int front=0,rear=0,Q[10];//定义队,front=0,rear=0分别为头和尾
    char l,r;//因为当没有左右孩子的时候会输入'-',所以先定义一个char类型,再进行判断让类型转换赋值给结构体
    scanf("%d\n",&N);//输出结点个数
    if(N){//注意后面要加上"\n"否则换行符会被当做字符输出
    for(i=0;i<N;i++){//将数据存储在结点当中
        scanf("%c %c\n",&l,&r);//输出左右孩子
        if(l!='-')
            T[i].left=l-'0';//类型转换
        else
            T[i].left=-1;//如果没有孩子就赋值为-1
        if(r!='-')
            T[i].right=r-'0';
        else
            T[i].right=-1;
       }
    }
    for(i=0;i<N;i++)//寻找根结点,因为根结点没有双亲,不是谁的孩子,所以在输入从0到N-1个数字中不会出现根结点的编号,所以使用遍历输入的左右孩子,如果,左右孩子不为空就将其标记为1,然后再遍历看标记数组中哪一个为0,为0的那个数组元素的下标就是根结点
    {
        if(T[i].left!=-1)
            book[T[i].left]=1;
        if(T[i].right!=-1)
            book[T[i].right]=1;
    }
    for(i=0;i<N;i++){
        if(book[i]==0){
            Q[front]=i;//将根结点入队
            rear++;//将尾指针后移到1
            break;
        }
    }
    while(rear-front){//如果队列不为空就执行循环
        if(T[Q[front]].right==-1&&T[Q[front]].left==-1){//首先判断左右孩子是否为空,如果都为空那么就是叶子结点,就将其输出
            if(flag)//flag在初始化的时候为0,刚开始的时候输出第一个叶子节点,flag=0,所以不会输出空格,在输出第一个结点之后就将flag定为1,之后的叶子结点进行输出的时候都会先输出空格。达到末尾没有空格输出的结果
                printf(" ");
            printf("%d",Q[front]);
            flag=1;
        }
        else{//如果有左右孩子就将其入队
            if(T[Q[front]].left!=-1)
                Q[rear++]=T[Q[front]].left;
            if(T[Q[front]].right!=-1)
                Q[rear++]=T[Q[front]].right;
        }
        front++;//将前面的结点不断出队,进行判断下一结点是否为叶子结点
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值