由二叉树的层序和中序序列输出二叉树的先序和后序序列。
输入格式:
每个测试包含多个测试用例。
第一行包含一个正整数T(1≤T≤10),表示测试用例的数量,测试用例的描述如下。
第二行一个N(1≤N≤1000)表示二叉树的节点个数
第三行N个数表示二叉树的层序
第四行N个数表示二叉树的中序
题目保证1~N每个数字有且仅出现一次
输入样例:
1
8
1 2 3 4 5 6 7 8
7 4 8 2 5 1 6 3
输出样例:
1 2 4 7 8 5 3 6
7 8 4 5 2 6 3 1
上面这题呢,想得挺久的,对树的知识好弱啊。
所以这道题我来总结下:
题目很简单,就是给你中序和层序让你把这颗树建立起来,然后输出先序和后序。
首先:我们应该先去寻找层序的第一个节点在中序的什么位置,因为层序的第一个节点一定是根节点,所以我们再接收中序的时候,顺便把顺序记住,然后就是去建树,范围从1到n寻找根节点在中序的什么位置;然后递归左子树和递归右子树。
我们应该在创建应该结构体,存放左右儿子,这里就不用指针了,太麻烦,我们直接用整形就行了,如struct Tree{int l,int r;}; 然后创建一个数组,存放节点。最好我们再输出先序和后序,这个很简单,就遍历就行了。这里有个注意点,因为是多个样例,所以每次都要把结构体数组清空一下。
下面是我的代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1020;
struct Node{int l,r;};
Node a[N];
int n,t;
int in[N];
int level[N];
int mp[N];
int build(int l,int r){
int root;
int k;
for(int i=1;i<=n;i++){
if(mp[level[i]]>=l&&mp[level[i]]<=r){
root=level[i];
break;
}
}
k=mp[root];
if(k>l)a[root].l=build(l,k-1);
if(k<r)a[root].r=build(k+1,r);
return root;
}
void print(int root){
cout<<root<<" ";
if(a[root].l)print(a[root].l);
if(a[root].r)print(a[root].r);
}
void print1(int root){
if(a[root].l)print1(a[root].l);
if(a[root].r)print1(a[root].r);
cout<<root<<" ";
}
int main(){
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++)cin>>level[i];
for(int i=1;i<=n;i++){
cin>>in[i];
mp[in[i]]=i;
}
int root=build(1,n);
print(root);
cout<<endl;
print1(root);
cout<<endl;
memset(a,0,sizeof(a));
}
return 0;
}