二叉树的构建与遍历
利用几个题目来回顾下如何根据二叉树的不同遍历次序构建一棵树,之后再对这棵树进行相应的操作。
1.sdut problem 1489 - 求二叉树的先序遍历
题目链接:http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=1489
题目大意
根据二叉树的后序遍历与中序遍历,求先序遍历。
题解
根据两个顺序,可以递归的将一棵树建立,之后递归输出数的先序遍历。
代码如下:
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
const int maxn = 100;
int t;
char s1[maxn], s2[maxn];
struct node {
char key;
node *lson, *rson;
node():lson(NULL),rson(NULL){}
};
node* _build(node* p, int l, int r, int pos) {
int i;
bool flag = false;
for(i = l; i <= r; i++) {
if(s1[i] == s2[pos]) {
flag = true;
break;
}
}
if(!flag)return NULL;
p = new node();
p->key = s1[i];
p->lson = _build(p->lson, l, i-1, pos-1-(r-i));
p->rson = _build(p->rson, i+1, r, pos-1);
return p;
}
void _pre(node* p) {
if(p != NULL) {
printf("%c", p->key);
_pre(p->lson);
_pre(p->rson);
}
}
int main() {
while(~scanf("%d", &t)) {
while(t--) {
scanf("%s%s", s1, s2);
int len = strlen(s1);
node *root;
root = _build(root, 0, len-1, len-1);
_pre(root);
printf("
");
}
}
return 0;
}
2.PAT 天梯赛 L2-006 树的遍历
题目链接:https://www.patest.cn/contests/gplt/L2-006
题目大意
根据二叉树的中序遍历与后序遍历,输出层次遍历序列。
题解
同样构建一棵树,利用BFS
得到层次遍历。
代码如下:
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 35;
int n;
int s1[maxn],s2[maxn];
struct node {
int key;
node *lson, *rson;
node():lson(NULL),rson(NULL){}
}*root;
node* _build(node* p, int l, int r, int pos) {
int i;
bool flag = false;
for(i = l; i <= r; i++) {
if(s1[pos] == s2[i]) {
flag = true;
break;
}
}
if(!flag) return NULL;
p = new node();
p->key = s1[pos];
p->lson = _build(p->lson, l, i-1, pos-1-(r-i));
p->rson = _build(p->rson, i+1, r, pos-1);
return p;
}
void bfs() {
queue<node*> q;
q.push(root);
int cnt = 0;
while(!q.empty()) {
node *p = q.front(); q.pop();
if(cnt) printf(" ");
cnt = 1;
printf("%d", p->key);
if(NULL != p->lson) {
q.push(p->lson);
}
if(NULL != p->rson) {
q.push(p->rson);
}
}
printf("
");
}
int main() {
while(~scanf("%d", &n)) {
for(int i = 0; i < n; i++) {
scanf("%d", &s1[i]);
}
for(int i = 0; i < n; i++) {
scanf("%d", &s2[i]);
}
root = _build(root, 0, n-1, n-1);
bfs();
}
return 0;
}
3.UVa problem 122 - Trees on the level
题目大意
输入一棵二叉树,每个节点都是按照从根节点到它的移动序列给出(数字表示节点的编号,L表示左,R表示右边)。现在根据给出的信息输出这棵树的层次遍历序列。
题解
按照给的节点,模拟建立一棵树。之后用一次BFS
得到树的层次遍历。
代码如下:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 300;
char s[maxn];
bool failed;
vector<int> ans;
struct Node {
bool have_value;
int v;
Node *left, *right;
Node():have_value(false),left(NULL),right(NULL){}
}*root;
void _build(int v, char *s) {
Node *u = root;
int len = strlen(s);
for(int i = 0; i < len; i++) {
if('L' == s[i]) {
if(NULL == u->left) u->left = new Node();
u = u->left;
}else if('R' == s[i]) {
if(NULL == u->right) u->right = new Node();
u = u->right;
}
}
if(u->have_value){
failed = true;
return ;
}
u->have_value = true;
u->v = v;
}
bool read_input() {
failed = false;
root = new Node();
while(true) {
if(scanf("%s", s) != 1) return false;
if(!strcmp(s, "()")) break;
int v;
sscanf(&s[1], "%d", &v);
_build(v, s);
}
return true;
}
bool bfs() {
ans.clear();
queue<Node*> q;
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() {
while(read_input()) {
if(!bfs()) failed = true;
if(failed) {
printf("not complete
");
}else {
for(int i = 0; i < ans.size(); i++) {
if(i) printf(" ");
printf("%d", ans[i]);
}
printf("
");
}
}
return 0;
}
4.UVa problem 548 - Tree
题目大意
给一棵点带权的二叉树的后序遍历与中序遍历,找到一个叶子使得它到跟的路径上的权和最小,如果有多解,输出叶子权值最小的那个。
题解
构建二叉树,DFS
递归的遍历这棵树,得到解。
代码如下:
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<cstdlib>
using namespace std;
const int maxn = 10000+10;
const int inf = 0x3f3f3f3f;
int inorder[maxn],postorder[maxn];
int n, _min, ans;
struct Node {
int value;
Node *lson, *rson;
Node():lson(NULL),rson(NULL){}
}*root;
Node* _build(Node* p, int l, int r, int pos) {
int i;
bool flag = false;
for(i = l; i <= r; i++) {
if(postorder[pos] == inorder[i]) {
flag = true;
break;
}
}
if(!flag) return NULL;
p = new Node();
p->value = postorder[pos];
p->lson = _build(p->lson, l, i-1, pos-1-(r-i));
p->rson = _build(p->rson, i+1, r, pos-1);
return p;
}
void _find(Node *p, int sum) {
if(NULL == p)return ;
sum += p->value;
if(NULL == p->lson && NULL == p->rson) {
if(_min > sum) {
_min = sum;
ans = p->value;
}else if(_min == sum) {
ans = (ans > p->value ? p->value: ans);
}
return ;
}
_find(p->lson, sum);
_find(p->rson, sum);
return ;
}
bool read_input(int *a) {
string line;
if(!getline(cin, line)) return false;
int x;
n = 0;
stringstream ss(line);
while(ss >> x)a[n++] = x;
return n>0;
}
int main() {
while(read_input(inorder)) {
read_input(postorder);
root = _build(root, 0, n-1, n-1);
_min = inf;
ans = inf;
_find(root, 0);
printf("%d
", ans);
}
return 0;
}