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% 通过 给出一棵二叉树,返回其节点值从底向上的层次序遍历(按从叶节点所在层到根节点所在的层遍历,然后逐层从左往右遍历) 您在真实的面试中是否遇到过这个 ...
随机推荐
- 使用Assetbundle时可能遇到的坑
原地址:http://www.cnblogs.com/realtimepixels/p/3652128.html 一 24 十一郎未分类 No Comments 转自 http://www.unity ...
- TKStudio 4.6IDE Warning: L6310W: Unable to find ARM libraries.
我也遇到了同样的问题.搞了很久,按下面的操解决了 内容转至:http://bbs.zlgmcu.com/dv_rss.asp?s=xh&boardid=43&id=23032& ...
- 浅谈javascript中的数据类型和引用类型
1.概述 javascript中有五种简单数据类型和一种复杂数据类型. 分别是:undefind, null, number, string ,boolean ----简单数据类型 ...
- java 格式化代码 不进行换行
此处无声胜有声.
- 解析Java中静态变量与实例变量的区别
java类的成员变量有俩种:一种是被static关键字修饰的变量,叫类变量或者静态变量:另一种没有static修饰,为实例变量. 在语法定义上的区别:静态变量前要加static关键字,而实例 ...
- lintcode:逆序对
题目 在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.给你一个数组,求出这个数组中逆序对的总数.概括:如果a[i] > a[j] 且 i < j, a[i] ...
- Project Euler 101 :Optimum polynomial 最优多项式
Optimum polynomial If we are presented with the first k terms of a sequence it is impossible to say ...
- ubuntu14.04安装MATLAB R2014a
1. 首先现在matlab2014a,http://pan.baidu.com/s/1pJGF5ov [Matlab2014a(密码:en52).该文件下载解压后如下所示: 2. 解压解压包(用lin ...
- Java7编程 高级进阶学习笔记--嵌套类
定义: 在一个类中定义的类叫做嵌套类. 作用: 1.允许对相关类进行逻辑分组 2.增强了代码的封装性 3.使代码具有更强的可读性和维护性 使用方式: package com.cmz.baseTest; ...
- HttpClient基本用法
<Apache HttpClient 4.3开发指南> Apache HttpClient 4系列已经发布很久了,但由于它与HttpClient 3.x版本完全不兼容,以至于业内采用此库的 ...