L2-006 树的遍历 (25 分)
给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数N(≤30),是二叉树中结点的个数。第二行给出其后序遍历序列。第三行给出其中序遍历序列。数字间以空格分隔。
输出格式:
在一行中输出该树的层序遍历的序列。数字间以1个空格分隔,行首尾不得有多余空格。
输入样例:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
输出样例:
4 1 6 3 5 7 2
code:
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
vector<int> post, in, level(100000, -1);
void pre(int root,int start,int end,int index) //root为根在后序序列中的位置 start end为该树在中序序列中的范围
{
if(start>end) return ;//递归结束
int i=start;
while(i<end&&in[i]!=post[root]) i++;//寻找根在中序中的位置 将树分割成两部分 为啥不是<=
level[index]=post[root];
pre(root-(end-i)-1,start,i-1,2*index+1);//遍历左子树 root-(end-i)-1即 减去右子树结点个数就是左子树的根的位置
pre(root-1,i+1,end,2*index+2);//遍历右子树 root-1即右子树的根节点位置
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int a;
scanf("%d",&a);
post.push_back(a);
}
for(int i=0;i<n;i++)
{
int a;
scanf("%d",&a);
in.push_back(a);
}
pre(n-1,0,n-1,0);
for(int i=0;i<level.size();i++)
{
if(level[i]!=-1)
{
if(i!=0)
cout<<" ";
cout<<level[i];
}
}
}
利用level数组存储层序序列。从根开始遍历,找到根之后就可以将中序序列分成左子树与右子树,再根据左右子树的长度,可以在后序序列中找到左右子树对应的根,这样一层一层的遍历下来,就可以得到层序序列。