题意
给你一棵树的后序遍历和中序遍历,求这棵树的层次遍历
思路
有两个问题
1.如何用后序和中序来构造一棵二叉树
2.如何层次遍历一颗二叉树
构造二叉树
已知后序的访问顺序为 左右根
中序的访问顺序问 左根右
那么对于一颗树来说后序的最后一个元素就是当前树的根,那么我们考虑每一颗子树,只要确定了子树的在后序中是那一部分,那这一部分的最后一个元素就是这颗子树的根了,那么正好我们可以通过中序来确定左右子树是哪些,举个例子,节点数为7的后序和中序,那么我们可以画出树来
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
4
/ \
1 6
\ / \
3 5 7
/
2
对于一开始的树来说后序的最后一个元素4就是整颗树的根,然后我们去中序中找左子树是哪些,右子树是哪些,发现 1 2 3 为其左子树且大小为3,5 6 7为其右子树且大小为三,那么对于左子树来说,由于后序是先遍历左,所以从开始的大小为3的元素都是左子树,那么我们知道2 3 1 为左子树的后序,根据后序的性质最后一个元素是根节点,那么我们就找到了,这颗左子树的根节点了,然后再去中序中寻找左子树的左右子树是哪些,发现其左子树的左子树为长度为0,说明左子树没有左子树了,左子树的右子树是2 3,然后就是重复上述的步骤,就可以用递归来做了就能构建出一颗二叉树了
层次遍历
层次遍历用队列代替栈然后依次对当前的节点的左儿子入队,右儿子入队就可以了
#include <bits/stdc++.h>
using namespace std;
typedef struct BiTNode
{
int c;
BiTNode *lchild,*rlchid;
} BiTNode,*BiTree;
int post[35];
int in[35];
int cnt;
BiTree build(int postL,int postR,int inL,int inR)
{
BiTree T=new BiTNode;
T->c=post[postR];
int Lnum,Rnum,pos;
for(int i=inL;i<=inR;i++)
{
if(post[postR]==in[i])
{
pos=i;
Lnum=i-inL;
Rnum=inR-i;
break;
}
}
if(Lnum)
{
T->lchild=build(postL,postL+Lnum-1,inL,pos-1);
}
else
T->lchild=NULL;
if(Rnum)
T->rlchid=build(postR-Rnum,postR-1,pos+1,inR);
else
T->rlchid=NULL;
return T;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&post[i]);
for(int i=0;i<n;i++)
scanf("%d",&in[i]);
BiTree T=build(0,n-1,0,n-1);
queue<BiTree>q;
int cnt=0;
q.push(T);
while(!q.empty())
{
T=q.front();
q.pop();
if(T!=NULL)
{
if(T->lchild!=NULL)
q.push(T->lchild);
if(T->rlchid!=NULL)
q.push(T->rlchid);
}
if(cnt++!=n-1)
printf("%d ",T->c);
else
printf("%d\n",T->c);
}
return 0;
}