题目要求
本题要求根据给定的一棵二叉树的后序遍历和中序遍历结果,输出该树的先序遍历结果。
输入格式:
第一行给出正整数N(≤30),是树中结点的个数。随后两行,每行给出N个整数,分别对应后序遍历和中序遍历结果,数字间以空格分隔。题目保证输入正确对应一棵二叉树。
输出格式:
在一行中输出Preorder:
以及该树的先序遍历结果。数字间有1个空格,行末不得有多余空格。
输入样例:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
输出样例:
Preorder: 4 1 3 2 6 5 7
问题分析
首先我们知道给定一棵二叉树三个遍历中的中序和前序或后续,我们可以求出另外一个的遍历,主要通过的是不同遍历根所在的位置来确定的,下面来分析一下这个过程。
当我们通过二叉树的后续遍历确定根节点的的值,我们便可以在中序遍历中找到这个值,如上图,找到了中序遍历的根是4处在4号位置。
那么通过中序遍历的性质,左根右,我们就可以确定,4左边的就是左子树,4右边的就是右子树,于是我们可以递归的处理一下两棵子树。
当我们找出左子树的时候,我们依然可以用上述方法,找到左子树的根以及他的左右子树
关系
我们假设一个树根的位置为,起点为,终点为,通过后续遍历的最后一个元素我们可以找出树根,然后再遍历一下中序遍历,找到根在中序遍历中出现的位置记为,然后他的左右两边分别是左右子树,于是我们可以确定左右子树在中序遍历中开始和结束的位置
左 开始: start 结束 i-1
右 开始 i+1 结束 end
然后我们来找根节点的位置,分别是左右子树的最后一个元素,由于root表示的是后序遍历中根的位置,所以我们左右子树的根分别为
左 root-(end-i)-1
右 root-1
于是我们就可以开始递归了。
代码
#include<bits/stdc++.h>
using namespace std;
int a[100],b[100];
typedef struct tree
{
int data;
struct tree *lchild,*rchild;
}*Bitree,Binode;//创建一棵树
Bitree init()
{
Bitree p=new Binode;
p->rchild=p->lchild=NULL;
return p;
}
Bitree find(int root,int start,int end)//寻找根节点的位置,
{
Bitree p=init();
p->data=a[root];//通过后序遍历找到根的位置
for(int i=start;i<=end;i++)//y表示起点
{
if(b[i]==a[root])//在中序遍历中找到根的位置
{
if(i!=start)//说明是有左子树的,然后递归的去左子树中寻找
{
p->lchild=find(root-(end-i)-1,start,i-1);//左子树根节点的位置
}
if(i!=end)
{
p->rchild=find(root-1,i+1,end);
}
}
}
return p;
}
void preorder(Bitree t)
{
if(t)
{
cout<<" "<<t->data;
preorder(t->lchild);
preorder(t->rchild);
}
}
int main()
{
int n;cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=n;i++)
cin>>b[i];
Bitree t=find(n,1,n);
cout<<"Preorder:";
preorder(t);
return 0;
}