uva 122 树的层次遍历

背景

Trees are fundamental in many branches of computer science. Current state-of-the art parallel computers such as Thinking Machines' CM-5 are based on fat trees. Quad- and octal-trees are fundamental to many algorithms in computer graphics.

This problem involves building and traversing binary trees.

 

题目

Given a sequence of binary trees, you are to write a program that prints a level-order traversal of each tree. In this problem each node of a binary tree contains a positive integer and all binary trees have have fewer than 256 nodes.

In a level-order traversal of a tree, the data in all nodes at a given level are printed in left-to-right order and all nodes at level k are printed before all nodes at level k+1.

For example, a level order traversal of the tree

is: 5, 4, 8, 11, 13, 4, 7, 2, 1.

In this problem a binary tree is specified by a sequence of pairs n,s) where n is the value at the node whose path from the root is given by the string s. A path is given be a sequence of L's and R's where L indicates a left branch and R indicates a right branch. In the tree diagrammed above, the node containing 13 is specified by (13,RL), and the node containing 2 is specified by (2,LLR). The root node is specified by (5,) where the empty string indicates the path from the root to itself. A binary tree is considered to be completely specifiedif every node on all root-to-node paths in the tree is given a value exactly once

输入

The input is a sequence of binary trees specified as described above. Each tree in a sequence consists of several pairs (n,s) as described above separated by whitespace. The last entry in each tree is (). No whitespace appears between left and right parentheses.

All nodes contain a positive integer. Every tree in the input will consist of at least one node and no more than 256 nodes. Input is terminated by end-of-file.

 

输出

For each completely specified binary tree in the input file, the level order traversal of that tree should be printed. If a tree is not completely specified, i.e., some node in the tree is NOT given a value or a node is given a value more than once, then the string ``not complete'' should be printed.

样例

(11,LL) (7,LLL) (8,R)
(5,) (4,L) (13,RL) (2,LLR) (1,RRR) (4,RR) ()
(3,L) (4,R) ()

 样例输出

5 4 8 11 13 4 7 2 1
not complete

题目意思很简单,就是建立一棵二叉树,让你按层次输出每个节点的权值,层次输出的部分很简单,只需要bfs简单处理一下就可以,所以本题的重点在于建树部分,对于建树,我们首先要学会使用一些小技巧来解决输入的问题,比如说
sscanf(&s[1],"%d",&v);//可以直接从字符串中读取数字 addnode(v,strchr(s,',')+1);//把括号一起读上,在建树时不考虑即可 ,这些都是一些很好用的输入技巧
之后我们使用指针的写法建树,第一次写发现有很多问题,需要注意很多细节。在结构体中定义函数,新建节点是要new一个新空间按顺序建树并且插入每个点的权值,按照顺序模拟即可,需要注意的是要加一些判断避免出现空树,具体细节可以看代码注释
#include<bits/stdc++.h>
using namespace std;
struct Node{
    int v ;//权值 
    Node* left,*right ;//建左子树和右子树 
    int have_value ;
    Node():have_value(false),left(NULL),right(NULL){} ;
} ;
Node* root ;//根节点
Node* newnode(){
    return new Node() ; //返回一个新结点 
} 
bool failed ;
void addnode(int v,char* s){//添加新结点 
    int n = strlen(s);//要进入树的第几层 
    Node* u = root ;
     for(int i = 0;i < n;i++)//找到要加入的位置 
     {
         if(s[i] == 'L'){
             if(u->left == NULL) u->left = newnode();//->为引用操作,引用指针时使用较多 
             u = u->left;//进入子树 
         }    
         else if(s[i] == 'R'){
             if(u->right == NULL) u->right= newnode();
             u = u->right ;
         }
     }
     if(u->have_value) failed = true ;//是否已经被访问过;
     u->v = v;
     u->have_value = true; 
} 
void freetree(Node* u){ //释放内存 ,递归写法 
    if(u == NULL) return ;
    freetree(u->left);
    freetree(u->right);
    delete u;
}
char s[1005];
bool read_input(){
    failed = false ;
    freetree(root) ;//初始化 
    root = newnode();
    while(true){
        if(scanf("%s", s) != 1) return false;
        if(!strcmp(s,"()")) break;
        int v ;
        sscanf(&s[1],"%d",&v);//可以直接从字符串中读取数字 
        addnode(v,strchr(s,',')+1);//把括号一起读上,在建树时不考虑即可 
    } 
    return true ;
} 
bool bfs(vector<int>& ans){//搜索 
    queue<Node*> q;
    ans.clear();
    q.push(root);
    while(!q.empty()){
        Node *u = q.front();q.pop();
        if(!u->have_value) return false;//如果有空树,及输入错误 
        ans.push_back(u->v);//加入答案数组 
        if(u->left != NULL)    q.push(u->left);//加入左子树 
        if(u->right != NULL) q.push(u->right);//加入右子树 
    } 
    return true ;
}
int main()
{
    vector<int> ans;
    while(read_input()){
        if(!bfs(ans)) failed = 1;
        if(failed) printf("not complete\n");
        else{
            for(int i = 0;i < ans.size();i++)
            {
                if(i != 0) cout << " " ;
                   cout << ans[i];
            }
            cout << endl ;
        }    
    }
    return 0;
}

 

posted @ 2020-09-20 21:25  徒手拆机甲  阅读(122)  评论(0)    收藏  举报