题意:

输入一颗二叉树,按照(左右左右, 节点的值)的格式。然后从上到下从左到右依次输出各个节点的值,如果一个节点没有赋值或者多次赋值,则输出“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. 去“IOE”

    所谓去“IOE”,是对去“IBM.Oracle.EMC”的简称,三者均为海外IT巨头,其中IBM代表硬件以及整体解决方案服务商,Oracle代表数据库,EMC代表数据存储.去“IOE”策略更广泛的理解 ...

  2. HDU Destroy Transportation system(有上下界的可行流)

    前几天正看着网络流,也正研究着一个有上下界的网络流的问题,查看了很多博客,觉得下面这篇概括的还是相当精确的: http://blog.csdn.net/leolin_/article/details/ ...

  3. UITableView多选全选

    自定义cell和取到相应的cell就行了 TableViewCell.h #import <UIKit/UIKit.h> @interface TableViewCell : UITabl ...

  4. POJ 2014

    #include <iostream> using namespace std; int main() { //freopen("acm.acm","r&qu ...

  5. 树莓派/RaspberryPi 内核编译

    1.获取所需源码 1)下载地址: 官方网址:https://github.com/raspberrypi 上面列出了树莓派所有的开源软件: linux:内核源码 tools:编译内核和其他源码所需的工 ...

  6. 关于WII光枪定位的设计(转)

    方法1. 简单1 LED方法 这是一个很忽悠的方法,把LED看成是屏幕中心,把光枪摄像头的视野范围看作是屏幕范围. 假设WII枪头摄像头的数据范围为[0,1024]*[0,768],显示器屏幕分辨率为 ...

  7. jenkins创建git任务连接时遇到的问题

    jenkins 创建任务后 配置 git时 报错 Jenkins Host key verification failed jenkins: Failed to connect to reposito ...

  8. 客户端用httpurlconnection来进行http连接的

    客户端用httpurlconnection来进行http连接的,并设置restful风格 请求响应流程 设置连接参数的方法 setAllowUserInteraction setDoInput set ...

  9. 《jQuery风暴》第2章 必须知道的JavaScript知识

    第2章 必须知道的JavaScript知识 JavaScript是jQuery应用的基础,掌握JavaScript这门语言是使用jQuery的基础条件.本章不会全面细致的讲解JavaScript的全部 ...

  10. photoshop:找不到增效工具入口点

    按Ctrl+k+9 ,到预设的增效工具栏设置为要存储的文件夹路径: