题意:

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

一、指针方式实现二叉树

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

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

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

 #define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue> const int maxn = ;
char s[maxn];
bool failed;
std::vector<int> ans; struct Node
{
bool have_value; //是否赋值过
int v;
Node *left, *right;
Node():have_value(false), left(NULL), right(NULL) {} //构造函数
};
Node* root; Node* newnode() { return new Node(); } //调用构造函数 void addnode(int v, char* s)
{
int n = strlen(s);
Node* u = root;
for(int i = ; 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 remove_tree(Node* u)
{
if(u == NULL) return;
remove_tree(u->left);
remove_tree(u->right);
delete u;
} bool read_input(void)
{
failed = false;
remove_tree(root);
root = newnode(); for(;;)
{
if(scanf("%s", s) != ) return false;
if(!strcmp(s, "()")) break;
int v;
sscanf(&s[], "%d", &v);
addnode(v, strchr(s, ',') + );
}
return true;
} bool BFS(std::vector<int>& ans)
{
std::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(void)
{
#ifdef LOCAL
freopen("122in.txt", "r", stdin);
#endif while(read_input())
{
if(failed || !BFS(ans)) printf("not complete\n");
else
{
printf("%d", ans[]);
for(int i = ; i < ans.size(); ++i)
printf(" %d", ans[i]);
puts("");
}
} return ;
}

代码君一

二、数组方式实现

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

 //#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector> const int maxn = ;
const int root = ;
char s[maxn];
bool have_value[maxn], failed;
int left[maxn], right[maxn], val[maxn], cnt;
std::vector<int> ans; void newtree(void)
{
left[root] = right[root] = ;
have_value[root] = false;
cnt = root;
} int newnode(void)
{
int u = ++cnt;
left[u] = right[u] = ;
have_value[u] = false;
return u;
} void addnode(int v, char* s)
{
int n = strlen(s);
int u = root;
for(int i = ; i < n; ++i)
{
if(s[i] == 'L')
{
if(left[u] == ) left[u] = newnode();
u = left[u];
}
else if(s[i] == 'R')
{
if(right[u] == ) right[u] = newnode();
u = right[u];
}
}
if(have_value[u]) failed = true; //如果一个节点有多次赋值,做标记
val[u] = v;
have_value[u] = true;
} bool read_input(void)
{
failed = false;
newtree(); for(;;)
{
if(scanf("%s", s) != ) return false;
if(!strcmp(s, "()")) break;
int v;
sscanf(&s[], "%d", &v);
addnode(v, strchr(s, ',') + );
}
return true;
} bool BFS(std::vector<int>& ans)
{
std::queue<int> q;
ans.clear();
q.push(root);
while(!q.empty())
{
int u = q.front();
q.pop();
if(!have_value[u]) return false;
ans.push_back(val[u]);
if(left[u] != ) q.push(left[u]);
if(right[u] != ) q.push(right[u]);
}
return true;
} int main(void)
{
#ifdef LOCAL
freopen("122in.txt", "r", stdin);
#endif while(read_input())
{
if(failed || !BFS(ans)) puts("not complete");
else
{
printf("%d", ans[]);
for(int i = ; i < ans.size(); ++i)
printf(" %d", ans[i]);
puts("");
}
} return ;
}

代码君二

三、内存池的方法

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

 //#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue> const int maxn = ;
char s[maxn];
bool failed;
std::vector<int> ans; struct Node
{
bool have_value; //是否赋值过
int v;
Node *left, *right;
Node():have_value(false), left(NULL), right(NULL) {} //构造函数
}node[maxn];
Node* root;
std::queue<Node*> freenodes; void Init()
{
for(int i = ; i < maxn; ++i)
freenodes.push(&node[i]); //初始化内存池
} Node* newnode()
{
Node* u = freenodes.front();
u->left = u->right = NULL;
u->have_value = false;
freenodes.pop();
return u;
} void deletenode(Node* u) { freenodes.push(u); } void addnode(int v, char* s)
{
int n = strlen(s);
Node* u = root;
for(int i = ; 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 remove_tree(Node* u)
{
if(u == NULL) return;
remove_tree(u->left);
remove_tree(u->right);
deletenode(u);
} bool read_input(void)
{
failed = false;
remove_tree(root);
Init();
root = newnode();
for(;;)
{
if(scanf("%s", s) != ) return false;
if(!strcmp(s, "()")) break;
int v;
sscanf(&s[], "%d", &v);
addnode(v, strchr(s, ',') + );
}
return true;
} bool BFS(std::vector<int>& ans)
{
std::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(void)
{
#ifdef LOCAL
freopen("122in.txt", "r", stdin);
#endif while(read_input())
{
if(failed || !BFS(ans)) printf("not complete\n");
else
{
printf("%d", ans[]);
for(int i = ; i < ans.size(); ++i)
printf(" %d", ans[i]);
puts("");
}
} return ;
}

代码君三

UVa 122 (二叉树的层次遍历) Trees on the level的更多相关文章

  1. Uva 122 树的层次遍历 Trees on the level lrj白书 p149

    是否可以把树上结点的编号,然后把二叉树存储在数组中呢?很遗憾如果结点在一条链上,那将是2^256个结点 所以需要采用动态结构 首先要读取结点,建立二叉树addnode()+read_input()承担 ...

  2. Trees on the level UVA - 122 (二叉树的层次遍历)

    题目链接:https://vjudge.net/problem/UVA-122 题目大意:输入一颗二叉树,你的任务是按从上到下,从左到右的顺序输出各个结点的值.每个结点都按照从根节点到它的移动序列给出 ...

  3. UVa 122 树的层次遍历

    题意: 给定一颗树, 按层次遍历输出. 分析: 用数组模拟二叉树, bfs即可实现层次遍历 #include <bits/stdc++.h> using namespace std; st ...

  4. [Swift]LeetCode107. 二叉树的层次遍历 II | Binary Tree Level Order Traversal II

    Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left ...

  5. 【遍历二叉树】04二叉树的层次遍历【Binary Tree Level Order Traversal】

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树,返回他的层次遍历的 ...

  6. LeetCode 102. 二叉树的层次遍历(Binary Tree Level Order Traversal) 8

    102. 二叉树的层次遍历 102. Binary Tree Level Order Traversal 题目描述 给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 每 ...

  7. lintcode : 二叉树的层次遍历II

    题目 二叉树的层次遍历 II 给出一棵二叉树,返回其节点值从底向上的层次序遍历(按从叶节点所在层到根节点所在的层遍历,然后逐层从左往右遍历) 样例 给出一棵二叉树 {3,9,20,#,#,15,7}, ...

  8. lintcode : 二叉树的层次遍历

    题目 二叉树的层次遍历 给出一棵二叉树,返回其节点值的层次遍历(逐层从左往右访问) 样例 给一棵二叉树 {3,9,20,#,#,15,7} : 3 / \ 9 20 / \ 15 7 返回他的分层遍历 ...

  9. LintCode 二叉树的层次遍历 II

    中等 二叉树的层次遍历 II 查看执行结果 42% 通过 给出一棵二叉树,返回其节点值从底向上的层次序遍历(按从叶节点所在层到根节点所在的层遍历,然后逐层从左往右遍历) 您在真实的面试中是否遇到过这个 ...

随机推荐

  1. Sqli-labs less 44

    Less-44 本关是基于盲注的,这里盲注主要是要没有报错信息,所以要采用盲注.这关与42关的区别就在于没有报错信息,同时,我们使用同样方式的payload: 登录 username:admin Pa ...

  2. windbg内核诊断方式--转载

    一.WinDbg是什么?它能做什么? WinDbg是在windows平台下,强大的用户态和内核态调试工具.它能够通过dmp文件轻松的定位到问题根源,可用于分析蓝屏.程序崩溃(IE崩溃)原因,是我们日常 ...

  3. acdream1116 Gao the string!(hash二分 or 后缀数组)

    问题套了一个斐波那契数,归根结底就是要求对于所有后缀s[i...n-1],所有前缀在其中出现的总次数.我一开始做的时候想了好久,后来看了别人的解法才恍然大悟.对于一个后缀来说 s[i...n-1]来说 ...

  4. POJ 2891 Strange Way to Express Integers (解一元线性方程组)

    求解一元线性同余方程组: x=ri(mod ai) i=1,2,...,k 解一元线性同余方程组的一般步骤:先求出前两个的解,即:x=r1(mod a1)     1x=r2(mod a2)     ...

  5. POJ 1650

    #include <iostream> #include <cmath> //wo de 编译器里的这个abs的功能不能用啊! using namespace std; int ...

  6. MySQL数据库优化总结

    对于一个以数据为中心的应用,数据库的好坏直接影响到程序的性能,因此数据库性能至关重要.一般来说,要保证数据库的效率,要做好以下四个方面的工作:数 据库设计.sql语句优化.数据库参数配置.恰当的硬件资 ...

  7. Logstash最佳实践

    http://udn.yyuap.com/doc/logstash-best-practice-cn/index.html

  8. Tomcat内存溢出(java.lang.OutOfMemoryError: PermGen space)的解决办法

    Tomcat启动时报如下错误: java.lang.OutOfMemoryError: PermGen space 解决办法: 配置相关内存大小.其中按照启动tomcat的不同方式,分如下三种情况 a ...

  9. URAL 1183 Brackets Sequence(DP)

    题目链接 题意 : 给你一串由括号组成的串,让你添加最少的括号使该串匹配. 思路 : 黑书上的DP.dp[i][j] = min{dp[i+1][j-1] (sh[i] == sh[j]),dp[i] ...

  10. 关于null == 0?返回false的问题

    1.首先我们先看各种情况的结果: null > 0? //=>false null < 0? //=>false null >= 0? //=>true null ...