Sicily---1156. Binary tree(树的数组存储,遍历,集合操作)

题目如下

Description
Your task is very simple: Given a binary tree, every node of which contains one upper case character (‘A’ to ‘Z’); you just need to print all characters of this tree in pre-order.
Input
Input may contain several test data sets.
For each test data set, first comes one integer n (1 <= n <= 1000) in one line representing the number of nodes in the tree. Then n lines follow, each of them contains information of one tree node. One line consist of four members in order: i (integer, represents the identifier of this node, 1 <= i <= 1000, unique in this test data set), c (char, represents the content of this node described as above, ‘A’ <= c <= ‘Z’), l (integer, represents the identifier of the left child of this node, 0 <= l <= 1000, note that when l is 0 it means that there is no left child of this node), r (integer, represents the identifier of the right child of this node, 0 <= r <= 1000, note that when r is 0 it means that there is no right child of this node). These four members are separated by one space.
Input is ended by EOF.
You can assume that all inputs are valid. All nodes can form only one valid binary tree in every test data set.
Output
For every test data set, please traverse the given tree and print the content of each node in pre-order. Characters should be printed in one line without any separating space.

分析:

题目明确指出最多只会有1000个节点 节点的给出并没有特定顺序 没有给出根节点

解决方法:

A.从分析的①来看,树的最大规模固定,适合用静态数组存储,从②来看,没有特定顺序意味着用动态存储需要经常添加和搜索,效率低
B.根节点不会是其他节点的孩子,因此可以用一个集合存所有节点,另一个存所有孩子(也就是非根节点),最后找出不是 “非根节点”的节点,即为根。这里由于查询次数较多,所以选用unordered_set

代码如下:
#include<stack>
#include<iostream>
#include<cmath>
#include<string>
#include<cstdio>
#include<algorithm>
#include<sstream>
#include<iomanip>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <tr1/unordered_set>//C++98的unordered_set放在tr1这个命名空间里面
using namespace std;
using namespace tr1;//C++98的unordered_set放在tr1这个命名空间里面

//定义节点类型 
struct Node {
    char data;
    int lc;
    int rc;
};

//用于储存树的数组 
Node tree[1010];

//树的前序遍历,用递归方法 
void pre_order(int root)
{
    cout << tree[root].data;
    if (tree[root].lc != 0)
        pre_order(tree[root].lc);
    if (tree[root].rc != 0)
        pre_order(tree[root].rc);
}


int main()
{
    //roots用于存储所有节点,chls用于存储非根节点 
    unordered_set<int> roots, chls;

    int n;
    while (cin >> n)
    {
        int pos, l, r;
        char c;
        while (n--)
        {
            cin >> pos >> c >> l >> r;
            tree[pos].data = c;
            tree[pos].lc = l;
            tree[pos].rc = r;

            roots.insert(pos);
            chls.insert(l);
            chls.insert(r);
        }

        int root;
        for (int i = 1; i < 1001; i++)
        {
            //如果找到一个节点不是 “非根节点”,那就是树的根 
            if (roots.find(i) != roots.end() && chls.find(i) == chls.end())
            {
                root = i;//用root记录下根 
                break;
            }
        }
        pre_order(root);//进行前序遍历 
        cout << endl;
        roots.clear();//清空集合,以便进行下一个计算 
        chls.clear();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值