中国大学MOOC-陈越、何钦铭-数据结构 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 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

思路:依我看来,这道题思路和树1差不多,甚至要比树1简单。两者存储树的方式都一样。不过,我在这里将节点原来存储key的位置并没有删除,而是让它保存节点在数组的下标。只有找叶子部分,我的思路是先找到根节点,然后从根节点开始,从上到下,从左到右遍历树,并把按照这样的顺序重新把树存储。这样,等下只需遍历这个数组,输出叶子节点,就可以符合题目的要求了。

代码如下:

#include<iostream>
using namespace std;
#define  MaxNum 10//数组的最大容量
#define ElementType int
#define Tree int
#define NULL -1//表示该节点为空
struct TreeNode{//树节点的表示
    ElementType index;//记录该节点的下标
    Tree left;//左子树
    Tree right;//右子树
}; 
int Num;//记录数组的实际大小
TreeNode T1[MaxNum];//用来记录输入的树
TreeNode T2[MaxNum];//重新排好的树
Tree BuildTree(struct TreeNode T[], int Num){
    char a;
    int i;
    int  check[MaxNum];//check数组的作用是辅助检测出根节点
    for (i = 0; i < Num; i++){ check[i] = 0; }
    for (i = 0; i < Num; i++){
        T[i].index=i;
        cin >> a;//输入左子树
        if (a != '-'){//对输入的数据进行判断
            T[i].left = a - '0';
            check[T[i].left] = 1;
        }//判断输入的类型是否是'-',如果是的话就赋值为-1,否则转化得到的数赋给T[i]的左子树,并且在check上记录
        else { T[i].left = NULL; }
        cin >> a;//输入右子树
        if (a != '-'){
            T[i].right = a - '0';
            check[T[i].right] = 1;
        }
        else { T[i].right = NULL; }
    }
    for (i = 0; i < Num; i++){//找到根节点
        if (!check[i])
            return i;}
}
int FindPos(int i){//找到插入的适合下标,并返回该下标
    for (int j = i; j < Num; j++){//从i开始查找,一直找到一个为空的项
        if (T2[j].index == NULL)
            return j;
    }
}
int Insert(int root){
    int count = 1;//记录叶子的个数
    int left, right;//记录左孩子的下标,记录右孩子的下标
    int pos;//记录要插入位置的下标
    for (int i = 0; i < MaxNum; i++){//初始化T2
        T2[i].index = T2[i].left = T2[i].right = NULL;
    }
    T2[0] = T1[root];//插入根节点
    for (int i = 1; i < Num; i++){
        left = T2[i - 1].left;
        right = T2[i - 1].right;
        if (left == NULL&&right == NULL){ count += 1; }
        if (left != NULL){//存在左孩子
            pos = FindPos(i);
            T2[pos] = T1[left];
        }
        if (right != NULL){//存在右孩子
            pos = FindPos(i);
            T2[pos] = T1[right];
        }
    }
    return count;//返回叶子的数目
}
void output(int count){//输出叶子
    int i;
    for (i = 0; count!=1; i++){
        if (T2[i].left == NULL&&T2[i].right == NULL){
            cout << T2[i].index << " ";
            count--;
        }
    }
    for (; i < Num; i++){//为了符合题目的输出要求
        if (T2[i].left == NULL&&T2[i].right == NULL)
            cout << T2[i].index;
    }
}
int main(){
    int r1;
    int count;
    cin >> Num;
    r1=BuildTree(T1, Num);
    count=Insert(r1);
    output(count);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值