本题有多组数据,输入处理到文件结束。
每组数据的第一行包括一个整数n,表示这棵二叉树一共有n个节点。
接下来的一行每行包括n个整数,表示这棵树的中序遍历。
接下来的一行每行包括n个整数,表示这棵树的前序遍历。
3<= n <= 100
4 2 5 1 6 3 7
1 2 4 5 3 6 7
分析:
二叉树的题目基本上都是要用递归的,这题也一样。
而递归的核心是找到结构相同的子问题。
二叉树如下所示:
a
↙ ↘
b c
↙↘ ↘
d e g
前序: abdecg
中序: dbeacg
由前序的第一个a,知道根节点是a,因而可以在中序的序列里把树分为两个部分,以a为分界的左子树
和右子树。在中序序列中找到a,左边部分则是左子树的中序,并可以得到左子树元素个数 l,右边则是右子树的中序,也能得到右子树的元素个数r。
同样前序序列里a的后面紧跟着的l个元素为左子树的前序,后面r个元素是右子树的前序。
所以要想打印后序遍历的结果,问题可分解为两个结构相同的小问题。
1,递归左子树的后序;
2,递归右子树的后序;
3,打印当前根节点。//后序最后打印;
类似的算法可以有中序和后序求先序。
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
int preorder[110];
int inorder[110];
int Find(int inl,int inr,int target)
{
for(int i = inl;i < inr; i++)
if(inorder[i] == target)
return i;
}
void posorder(int inl,int inr,int prel,int prer)
{
if(inr == inl) return;
int root = Find(inl,inr,preorder[prel]);
int len = root - inl;
posorder(inl,root,prel+1,prel+1+len);
posorder(root+1,inr,prel+1+len,prer);
printf("%d ",inorder[root]);
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i = 0; i < n; i++)
scanf("%d",&inorder[i]);
for(int i = 0; i < n; i++)
scanf("%d",&preorder[i]);
posorder(0,n,0,n);
printf("\n");
return 0;
}
}