题目链接 总时间限制: 500ms 内存限制: 65535kB 描述 我们知道如何按照三种深度优先次序来周游一棵二叉树,来得到中根序列、前根序列和后根序列。反过来,如果给定二叉树的中根序列和后根序列,或者给定中根序列和前根序列,可以重建一二叉树。本题输入一棵二叉树的中根序列和后根序列,要求在内存中重建二叉树,最后输出这棵二叉树的前根序列。

用不同的整数来唯一标识二叉树的每一个结点

中根序列是9 5 32 67

后根序列9 32 67 5

前根序列5 9 67 32

输入 两行。第一行是二叉树的中根序列,第二行是后根序列。每个数字表示的结点之间用空格隔开。结点数字范围0~65535。暂不必考虑不合理的输入数据。 输出 一行。由输入中的中根序列和后根序列重建的二叉树的前根序列。每个数字表示的结点之间用空格隔开。 样例输入

1
2
9 5 32 67
9 32 67 5
样例输出
1
5 9 67 32

关键在于利用通过后序找到每个子树的根节点,以此为界找到左、右子树,从而进行递归。 链式算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define N 65536

typedef struct node{
int data;
struct node * lc,*rc;
}BitNode,*BitTree;

int sLDR[N],sLRD[N];

BitTree BuildTree(int coStart,int coEnd,int loStart, int loEnd){
BitTree root = (BitTree)malloc(sizeof(BitNode));
root->data = sLRD[loEnd];
root->lc = NULL;
root->rc = NULL;
int i;

if(coStart == coEnd)
return root;
for(i = 0;i <= coEnd-coStart;i++){
if(sLDR[coStart+i] == sLRD[loEnd])
break;
}

if(i>=1) root->lc = BuildTree(coStart,coStart+i-1,loStart,loStart+i-1);
if(coEnd>=coStart+i+1) root->rc = BuildTree(coStart+i+1,coEnd,loStart+i,loEnd-1);
return root;
}

int visit(BitTree T){
printf("%d ",T->data);
return T->data;
}

int PreTranverse(BitTree T){
if(T){
visit(T);
if(T->lc)
PreTranverse(T->lc);
if(T->rc)
PreTranverse(T->rc);
}
return 1;
}

int main(){
//freopen("in.txt","r",stdin);
int s[N];
int order = 0;
int ch;
while((scanf("%d",&ch))!=EOF){
s[++order] = ch;
}
for(int i = 1;i <= order/2;i++)
sLDR[i] = s[i];
for(int i = 1;i <= order/2;i++)
sLRD[i] = s[order/2+i];
BitTree root = BuildTree(1,order/2,1,order/2);
PreTranverse(root);
printf("\n");
return 0;
}

顺序算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <cstdio>
#include <cstdlib>
#include <cstring>
#define N 65536

typedef struct node{
int data;
struct node * lc,*rc;
}BitNode,*BitTree;

int sLDR[N],sLRD[N];
int tree[N];

void BuildTree(int coStart,int coEnd,int loStart, int loEnd,int k){
//BitTree root = (BitTree)malloc(sizeof(BitNode));
tree[k] = sLRD[loEnd];
tree[2*k] = 0;
tree[2*k+1] = 0;
//root->lc = NULL;
//root->rc = NULL;
int i;

if(coStart == coEnd)
return ;
for(i = 0;i <= coEnd-coStart;i++){
if(sLDR[coStart+i] == sLRD[loEnd])
break;
}

if(i>=1) BuildTree(coStart,coStart+i-1,loStart,loStart+i-1,2*k);
if(coEnd>=coStart+i+1) BuildTree(coStart+i+1,coEnd,loStart+i,loEnd-1,2*k+1);
//return root;
}

int visit(int i){
printf("%d ",tree[i]);
return tree[i];
}

int PreTranverse(int i){
if(tree[i]){
visit(i);
if(tree[2*i])
PreTranverse(2*i);
if(tree[2*i+1])
PreTranverse(2*i+1);
}
return 1;
}

int main(){
//freopen("in.txt","r",stdin);
int s[N];
int order = 0;
int ch;
while((scanf("%d",&ch))!=EOF){
s[++order] = ch;
}
for(int i = 1;i <= order/2;i++)
sLDR[i] = s[i];
for(int i = 1;i <= order/2;i++)
sLRD[i] = s[order/2+i];
BuildTree(1,order/2,1,order/2,1);
PreTranverse(1);
printf("\n");
return 0;
}