1. 程式人生 > 實用技巧 >uva 122 樹的層次遍歷

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 onfat 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 alevel-ordertraversal of a tree, the data in all nodes at a given level are printed in left-to-right order and all nodes at levelk

are printed before all nodes at levelk+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) wherenis the value at the node whose path from the root is given by the strings. A path is given be a sequence ofL

's andR's whereLindicates a left branch andRindicates 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 becompletely 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;
}