zoukankan      html  css  js  c++  java
  • UVa 122 (二叉树的层次遍历) Trees on the level

    题意:

    输入一颗二叉树,按照(左右左右, 节点的值)的格式。然后从上到下从左到右依次输出各个节点的值,如果一个节点没有赋值或者多次赋值,则输出“not complete”

    一、指针方式实现二叉树

    首先定义一个结构体,然后定义一个结构体指针root,作为整棵树的根节点。如果需要用到左右节点则申请一个空间,也就是用不到的就不申请,以节省空间。

    遍历方式是广度优先遍历(BFS),从根节点依次拓展子节点,如果有子节点就入队,然后根节点出队。继续拓展,直到队列为空,即遍历完整棵树。

    因为指针丢失以后会造成内存泄露,所以在每次读取二叉树之前都要释放掉上一棵树申请的内存,二叉树的删除也是递归删除的。

      1 #define LOCAL
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <vector>
      6 #include <queue>
      7 
      8 const int maxn = 300;
      9 char s[maxn];
     10 bool failed;
     11 std::vector<int> ans;
     12 
     13 struct Node
     14 {
     15     bool have_value;    //是否赋值过
     16     int v;
     17     Node *left, *right;
     18     Node():have_value(false), left(NULL), right(NULL) {}    //构造函数
     19 };
     20 Node* root;
     21 
     22 Node* newnode()    { return new Node(); }    //调用构造函数
     23 
     24 void addnode(int v, char* s)
     25 {
     26     int n = strlen(s);
     27     Node* u = root;
     28     for(int i = 0; i < n; ++i)
     29     {
     30         if(s[i] == 'L')
     31         {
     32             if(u->left == NULL)    u->left = newnode();
     33             u = u->left;
     34         }
     35         else if(s[i] == 'R')
     36         {
     37             if(u->right == NULL)    u->right = newnode();
     38             u = u->right;
     39         }
     40     }
     41     if(u->have_value)    failed = true;    //如果一个节点有多次赋值,做标记
     42     u->v = v;
     43     u->have_value = true;
     44 }
     45 
     46 void remove_tree(Node* u)
     47 {
     48     if(u == NULL)    return;
     49     remove_tree(u->left);
     50     remove_tree(u->right);
     51     delete u;
     52 }
     53 
     54 bool read_input(void)
     55 {
     56     failed = false;
     57     remove_tree(root);
     58     root = newnode();
     59     
     60     for(;;)
     61     {
     62         if(scanf("%s", s) != 1) return false;
     63         if(!strcmp(s, "()"))    break;
     64         int v;
     65         sscanf(&s[1], "%d", &v);
     66         addnode(v, strchr(s, ',') + 1);
     67     }
     68     return true;
     69 }
     70 
     71 bool BFS(std::vector<int>& ans)
     72 {
     73     std::queue<Node*> q;
     74     ans.clear();
     75     q.push(root);
     76     while(!q.empty())
     77     {
     78         Node* u = q.front();
     79         q.pop();
     80         if(!u->have_value)    return false;    //该节点没有赋值过
     81         ans.push_back(u->v);
     82         if(u->left != NULL)    q.push(u->left);
     83         if(u->right != NULL)    q.push(u->right);
     84     }
     85     return true;
     86 }
     87 
     88 int main(void)
     89 {
     90     #ifdef LOCAL
     91         freopen("122in.txt", "r", stdin);
     92     #endif
     93 
     94     while(read_input())
     95     {
     96         if(failed || !BFS(ans))    printf("not complete
    ");
     97         else
     98         {
     99             printf("%d", ans[0]);
    100             for(int i = 1; i < ans.size(); ++i)
    101                 printf(" %d", ans[i]);
    102             puts("");
    103         }
    104     }
    105 
    106     return 0;
    107 }
    代码君一

    二、数组方式实现

    每新建一个节点计数器cnt就自增1,而不是像完全二叉树那样,左右子节点是父节点的二倍和二倍加1.

      1 //#define LOCAL
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <queue>
      6 #include <vector>
      7 
      8 const int maxn = 300;
      9 const int root = 1;
     10 char s[maxn];
     11 bool have_value[maxn], failed;
     12 int left[maxn], right[maxn], val[maxn], cnt;
     13 std::vector<int> ans;
     14 
     15 void newtree(void)
     16 {
     17     left[root] = right[root] = 0;
     18     have_value[root] = false;
     19     cnt = root;
     20 }
     21 
     22 int newnode(void)
     23 {
     24     int u = ++cnt;
     25     left[u] = right[u] = 0;
     26     have_value[u] = false;
     27     return u;
     28 }
     29 
     30 void addnode(int v, char* s)
     31 {
     32     int n = strlen(s);
     33     int u = root;
     34     for(int i = 0; i < n; ++i)
     35     {
     36         if(s[i] == 'L')
     37         {
     38             if(left[u] == 0)    left[u] = newnode();
     39             u = left[u];
     40         }
     41         else if(s[i] == 'R')
     42         {
     43             if(right[u] == 0)    right[u] = newnode();
     44             u = right[u];
     45         }
     46     }
     47     if(have_value[u])    failed = true;    //如果一个节点有多次赋值,做标记
     48     val[u] = v;
     49     have_value[u] = true;
     50 }
     51 
     52 bool read_input(void)
     53 {
     54     failed = false;
     55     newtree();
     56     
     57     for(;;)
     58     {
     59         if(scanf("%s", s) != 1) return false;
     60         if(!strcmp(s, "()"))    break;
     61         int v;
     62         sscanf(&s[1], "%d", &v);
     63         addnode(v, strchr(s, ',') + 1);
     64     }
     65     return true;
     66 }
     67 
     68 bool BFS(std::vector<int>& ans)
     69 {
     70     std::queue<int> q;
     71     ans.clear();
     72     q.push(root);
     73     while(!q.empty())
     74     {
     75         int u = q.front();
     76         q.pop();
     77         if(!have_value[u])    return false;
     78         ans.push_back(val[u]);
     79         if(left[u] != 0)    q.push(left[u]);
     80         if(right[u] != 0)    q.push(right[u]);
     81     }
     82     return true;
     83 }
     84 
     85 int main(void)
     86 {
     87     #ifdef LOCAL
     88         freopen("122in.txt", "r", stdin);
     89     #endif
     90 
     91     while(read_input())
     92     {
     93         if(failed || !BFS(ans))    puts("not complete");
     94         else
     95         {
     96             printf("%d", ans[0]);
     97             for(int i = 1; i < ans.size(); ++i)
     98                 printf(" %d", ans[i]);
     99             puts("");
    100         }
    101     }
    102 
    103     return 0;
    104 }
    代码君二

    三、内存池的方法

    静态申请一个Node数组配合一个空闲列表实现一个简单的内存池。

      1 //#define LOCAL
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <vector>
      6 #include <queue>
      7 
      8 const int maxn = 300;
      9 char s[maxn];
     10 bool failed;
     11 std::vector<int> ans;
     12 
     13 struct Node
     14 {
     15     bool have_value;    //是否赋值过
     16     int v;
     17     Node *left, *right;
     18     Node():have_value(false), left(NULL), right(NULL) {}    //构造函数
     19 }node[maxn];
     20 Node* root;
     21 std::queue<Node*> freenodes;
     22 
     23 void Init()
     24 {
     25     for(int i = 0; i < maxn; ++i)
     26         freenodes.push(&node[i]);    //初始化内存池
     27 }
     28 
     29 Node* newnode()
     30 {
     31     Node* u = freenodes.front();
     32     u->left = u->right = NULL;
     33     u->have_value = false;
     34     freenodes.pop();
     35     return u;
     36 }
     37 
     38 void deletenode(Node* u) { freenodes.push(u); }
     39 
     40 void addnode(int v, char* s)
     41 {
     42     int n = strlen(s);
     43     Node* u = root;
     44     for(int i = 0; i < n; ++i)
     45     {
     46         if(s[i] == 'L')
     47         {
     48             if(u->left == NULL)    u->left = newnode();
     49             u = u->left;
     50         }
     51         else if(s[i] == 'R')
     52         {
     53             if(u->right == NULL)    u->right = newnode();
     54             u = u->right;
     55         }
     56     }
     57     if(u->have_value)    failed = true;    //如果一个节点有多次赋值,做标记
     58     u->v = v;
     59     u->have_value = true;
     60 }
     61 
     62 void remove_tree(Node* u)
     63 {
     64     if(u == NULL)    return;
     65     remove_tree(u->left);
     66     remove_tree(u->right);
     67     deletenode(u);
     68 }
     69 
     70 bool read_input(void)
     71 {
     72     failed = false;
     73     remove_tree(root);
     74     Init();
     75     root = newnode(); 
     76     for(;;)
     77     {
     78         if(scanf("%s", s) != 1) return false;
     79         if(!strcmp(s, "()"))    break;
     80         int v;
     81         sscanf(&s[1], "%d", &v);
     82         addnode(v, strchr(s, ',') + 1);
     83     }
     84     return true;
     85 }
     86 
     87 bool BFS(std::vector<int>& ans)
     88 {
     89     std::queue<Node*> q;
     90     ans.clear();
     91     q.push(root);
     92     while(!q.empty())
     93     {
     94         Node* u = q.front();
     95         q.pop();
     96         if(!u->have_value)    return false;    //该节点没有赋值过
     97         ans.push_back(u->v);
     98         if(u->left != NULL)    q.push(u->left);
     99         if(u->right != NULL)    q.push(u->right);
    100     }
    101     return true;
    102 }
    103 
    104 int main(void)
    105 {
    106     #ifdef LOCAL
    107         freopen("122in.txt", "r", stdin);
    108     #endif
    109 
    110     while(read_input())
    111     {
    112         if(failed || !BFS(ans))    printf("not complete
    ");
    113         else
    114         {
    115             printf("%d", ans[0]);
    116             for(int i = 1; i < ans.size(); ++i)
    117                 printf(" %d", ans[i]);
    118             puts("");
    119         }
    120     }
    121 
    122     return 0;
    123 }
    代码君三
  • 相关阅读:
    django models设置联合主键
    sql语句清空表数据
    mysql交互模式下执行sql文件
    linux 下安装虚拟环境和创建虚拟环境
    解决Eclipse中无法直接使用sun.misc.BASE64Encoder及sun.misc.BASE64Decoder的问题
    mssql语法
    PowerDesigner的使用
    NoSuchMethodError错误
    在windows、widfly环境下,远程debug
    Blocking request failed HttpServerExchange{ GET /ssssssssss/kkk}: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/3984163.html
Copyright © 2011-2022 走看看