UVa 122 (二叉树的层次遍历) Trees on the level
题意:
输入一颗二叉树,按照(左右左右, 节点的值)的格式。然后从上到下从左到右依次输出各个节点的值,如果一个节点没有赋值或者多次赋值,则输出“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的更多相关文章
- Uva 122 树的层次遍历 Trees on the level lrj白书 p149
是否可以把树上结点的编号,然后把二叉树存储在数组中呢?很遗憾如果结点在一条链上,那将是2^256个结点 所以需要采用动态结构 首先要读取结点,建立二叉树addnode()+read_input()承担 ...
- Trees on the level UVA - 122 (二叉树的层次遍历)
题目链接:https://vjudge.net/problem/UVA-122 题目大意:输入一颗二叉树,你的任务是按从上到下,从左到右的顺序输出各个结点的值.每个结点都按照从根节点到它的移动序列给出 ...
- UVa 122 树的层次遍历
题意: 给定一颗树, 按层次遍历输出. 分析: 用数组模拟二叉树, bfs即可实现层次遍历 #include <bits/stdc++.h> using namespace std; st ...
- [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 ...
- 【遍历二叉树】04二叉树的层次遍历【Binary Tree Level Order Traversal】
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树,返回他的层次遍历的 ...
- LeetCode 102. 二叉树的层次遍历(Binary Tree Level Order Traversal) 8
102. 二叉树的层次遍历 102. Binary Tree Level Order Traversal 题目描述 给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 每 ...
- lintcode : 二叉树的层次遍历II
题目 二叉树的层次遍历 II 给出一棵二叉树,返回其节点值从底向上的层次序遍历(按从叶节点所在层到根节点所在的层遍历,然后逐层从左往右遍历) 样例 给出一棵二叉树 {3,9,20,#,#,15,7}, ...
- lintcode : 二叉树的层次遍历
题目 二叉树的层次遍历 给出一棵二叉树,返回其节点值的层次遍历(逐层从左往右访问) 样例 给一棵二叉树 {3,9,20,#,#,15,7} : 3 / \ 9 20 / \ 15 7 返回他的分层遍历 ...
- LintCode 二叉树的层次遍历 II
中等 二叉树的层次遍历 II 查看执行结果 42% 通过 给出一棵二叉树,返回其节点值从底向上的层次序遍历(按从叶节点所在层到根节点所在的层遍历,然后逐层从左往右遍历) 您在真实的面试中是否遇到过这个 ...
随机推荐
- 深入理解C# 静态类与非静态类、静态成员的区别
静态类 静态类与非静态类的重要区别在于静态类不能实例化,也就是说,不能使用 new 关键字创建静态类类型的变量.在声明一个类时使用static关键字,具有两个方面的意义:首先,它防止程序员写代码来实例 ...
- ftp命令和scp命令
ftp命令: 服务器有安装ftp Server,另外一台linux可以使用ftp的client程序来进行文件的拷贝读取和下载. 1. 连接ftp服务器 格式:ftp [hostname| ip-ad ...
- ZOJ3229 Shoot the Bullet(有源汇的上下界最大流)
#pragma warning(disable:4996) #include <iostream> #include <cstring> #include <string ...
- C#中反射泛型 CreateInstance
假设1我有个类叫SortClass,类中有个BubbleSort(int[] array)用于给数组进行排序. 假设2我有个类叫SortT<T>,类中有个BubbleSort(T[] ar ...
- C#中的Delegate
谈C#中的Delegate http://www.cnblogs.com/hyddd/archive/2009/07/26/1531538.html
- 两台笔记本搭建openvswitch网络
环境说明: 笔记本A.B均运行Ubuntu 14.04,两台笔记本通过无线网卡上网,用一根网线连接两台笔记本的有线网卡. 网络拓扑: 其中,vm1 vm2 S1位于笔记本A,vm3 vm4 S2位于笔 ...
- StructLayout特性(转)
StructLayout特性 StructLayout特性 公 共语言运行库利用StructLayoutAttribute控制类或结构的数据字段在托管内存中的物理布局,即类或结构需要 ...
- lintcode :最长公共前缀
题目 最长公共前缀 给k个字符串,求出他们的最长公共前缀(LCP) 样例 在 "ABCD" "ABEF" 和 "ACEF" 中, LCP ...
- android listview 加载图片错乱(错位)
写道 今天晚上一个朋友介绍我看了一篇文章,也是解决android中listview在加载图片错位的问题,看了之后,感觉写的很好,自己也遇到这个问题,但是又不知道从何下手,看到这篇文章后,我的问题 ...
- ffplay 中filter的使用
添加字幕:ffplay -vf drawtext="fontfile=arial.ttf: text='Test Text': x=100: y=300: \ fontsize=48: fo ...