题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5444
用先序和中序建立二叉树,同时记录父亲节点和方向。
然后递归输出解就可以了,用hash记录每个节点的地址,之后不需要再查找。
主要是复习一下二叉树重建。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
using namespace std;
const int maxn = 1005;
struct node {
// int label;
node* l;
node* r;
node* father;
char dir;
node (int lb) {
// label = lb;
l = r = father = 0;
dir = ' ';
}
~node() {
delete l;
delete r;
}
};
int preOrder[maxn];
int n;
node *hs[maxn]; // 用来映射树的节点的地址
node* build(int id, int s, int e, node* father, char dir) {
if(s > e) {
return 0;
}
int root = preOrder[id];
node* cur = new node(root);
cur->father = father;
cur->dir = dir;
hs[root] = cur;
cur->l = build(id + 1, s, root - 1, cur, 'E');
cur->r = build(id + (root - s) + 1, root + 1, e, cur, 'W');
return cur;
}
//void preOrder1(node* root) {
// if(root == 0) {
// return ;
// }
// printf("%d", root->label);
// preOrder1(root->l);
// preOrder1(root->r);
//}
void print(node* cur) {
if(cur->dir == 'r') {
return ;
}
print(cur->father);
printf("%c", cur->dir);
}
int main() {
int t, q, x;
// freopen("test.txt", "r", stdin);
scanf("%d", &t);
while (t --) {
scanf("%d", &n);
for (int i = 1; i <= n; i ++) {
scanf("%d", preOrder + i);
}
node *root = build(1, 1, n, 0, 'r');
// preOrder1(root);
scanf("%d", &q);
while (q --) {
scanf("%d", &x);
node *cur = hs[x];
// printf("%d %d\n", cur->father, cur->dir);
print(cur);
printf("\n");
}
}
return 0;
}
// 根据先序序列和中序序列,恢复二叉树
public BinNode<T> reBuilderPre(Object[] pre, Object[] ino) {
root = reBuilderPre(pre, ino, 0, 0, ino.length - 1);
return root;
}
private BinNode<T> reBuilderPre(Object[] pre, Object[] ino, int ps, int low, int high) {
if(low > high) {
return null;
}
T elem = (T) pre[ps];
BinNode<T> p = new BinNode<T>((T) pre[ps]);
int i = 0;
for (i = low; i <= high; i ++) {
if(elem.equals(ino[i])) {
break;
}
}
p.lchild = reBuilderPre(pre, ino, ps + 1, low, i - 1);
p.rchild = reBuilderPre(pre, ino, ps + (i - low) + 1, i + 1, high);
return p;
}
// 根据后序序列和中序序列,恢复二叉树
public BinNode<T> reBuilderPost(Object[] post, Object[] ino) {
root = reBuilderPost(post, ino, post.length - 1, 0, ino.length - 1);
return root;
}
private BinNode<T> reBuilderPost(Object[] post, Object[] ino, int ps, int low, int high) {
if(low > high) {
return null;
}
T elem = (T)post[ps];
BinNode<T> p = new BinNode<T>((T)post[ps]);
int i = 0;
for (i = low; i < high; i ++) {
if(elem.equals(ino[i])) {
break;
}
}
p.lchild = reBuilderPost(post, ino, ps - (high - i) - 1, low, i - 1);
p.rchild = reBuilderPost(post, ino, ps - 1, i + 1, high);
return p;
}