题目描述
给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列。这里假设键值都是互不相等的正整数。
输入格式:
输入第一行给出一个正整数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
思路分析
这种根据前序和中序求后序,后序和中序求前序的题思路大同小异。基本都是先建树,再按条件输出。
建树: 先找到根节点,利用递归再找到左子树的根和右子树的根,一直到叶节点。
输出: 四种输出在我上一篇博客里面有讲解,需要哪一种可以直接把相应的方法copy过来。有一点要注意的是输出格式要求最后不能有空格,我们可以设置一个变量初始为0,每次输出+1,在输出之前判断一下,如果不为0,就多输出一个空格。这样除了第一个前面没有空格,其他前面都有空格,就符合要求了。
源代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct TNode* BinTree;
struct TNode{
int Data;
BinTree Left;
BinTree Right;
};
BinTree getTree(int a[],int b[],int sum);
void Preorder(BinTree BT);
void LevelorderTraversal( BinTree BT ,int n);
int main(){
int n;
scanf("%d",&n);
int a[n],b[n];
for (int i = 0; i < n; i++) {
scanf("%d",&a[i]);
}
for (int j = 0; j < n; j++) {
scanf("%d",&b[j]);
}
BinTree BT=getTree(a,b,n);
LevelorderTraversal(BT,n);
return 0;
}
BinTree getTree(int a[],int b[],int sum){
int i;
BinTree BT;
if(sum==0)
return NULL;
else{
BT=(BinTree)malloc(sizeof(struct TNode));
BT->Data=a[sum-1];
for (i = 0; i < sum; i++) {
if(b[i]==a[sum-1])
break;
}
BT->Left=getTree(a,b,i);
BT->Right=getTree(a+i,b+1+i,sum-i-1);
}
return BT;
}
void Preorder(BinTree BT){
if(BT){
printf(" %d",BT->Data);
Preorder(BT->Left);
Preorder(BT->Right);
}
}
void LevelorderTraversal( BinTree BT ,int n){//层序
if(!BT)
return;
int len=1,pos,sum=0;
BinTree a[101],b[101];
a[0]=BT;
while(1){
if(len==0)
return;
pos=0;
for(int i=0;i<len;i++)
{
if(a[i]->Left!=NULL)//如果它的左节点不为空,就存到b数组里
b[pos++]=a[i]->Left;
if(a[i]->Right!=NULL)//如果它的右节点不为空,就存到b数组里
b[pos++]=a[i]->Right;
if(a[i]!=NULL){//不为空输出
printf("%d",a[i]->Data);
sum++;
}
if(sum!=n)
printf(" ");
}
len=pos;//更新下一层宽度,为下一次循环做准备
for(int i=0;i<len;i++)//将下层的b赋给a,为下一次循环做准备
a[i]=b[i];
}
}