Suppose that all the keys in a binary tree are distinct positive integers. Given the postorder and inorder traversal sequences, you are supposed to output the level order traversal sequence of the corresponding binary tree.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤30), the total number of nodes in the binary tree. The second line gives the postorder sequence and the third line gives the inorder sequence. All the numbers in a line are separated by a space.
Output Specification:
For each test case, print in one line the level order traversal sequence of the corresponding binary tree. All the numbers in a line must be separated by exactly one space, and there must be no extra space at the end of the line.
Sample Input:
7
2 3 1 5 7 6 4
1 2 3 4 5 6 7
Sample Output:
4 1 6 3 5 7 2
解题思路:
这道题的题意是说给你一个后序遍历序列和一个中序遍历序列,让你求出这棵二叉树的层序遍历序列。
大题思路就是从后序遍历和中序遍历中构建一棵二叉树,然后对这棵树进行层序遍历就行啦。
构建的时候我们采用分而治之的方法,建树的函数为如下
tree createTree(int left1, int right1, int left2, int right2){
//printf("(%d, %d, %d, %d)\n", left1, right1, left2, right2);
if(right1<left1 || right2<left2){
return NULL;
}
tree p = (node*)malloc(sizeof(node));
p->data = postorder[right1];
//printf("%d\n", p->data);
if(left2==right2){ //只有一个结点了
p->lchild = NULL;
p->rchild = NULL;
return p;
}
//寻找中序遍历中根节点的位置
int idx;
for(idx=left2; idx<=right2; idx++){
if(inorder[idx]==postorder[right1]){
break;
}
}
//计算左右子树的个数
int cntLeft = idx-left2;
int cntRight = right2-idx;
p->lchild = createTree(left1, left1+cntLeft-1, left2, idx-1);
p->rchild = createTree(left1+cntLeft, left1+cntLeft+cntRight-1, idx+1, right2);
return p;
}
我们知道后序遍历的最后一个元素就是当前子树的根节点,根据这个根节点我们就可以在中序遍历中找到根节点的左右两棵子树,然后递归进行这个过程就行啦
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 50
int postorder[MAXSIZE];
int inorder[MAXSIZE];
int n;
typedef struct node{
int data;
struct node* lchild;
struct node* rchild;
}*tree;
//根据后序遍历和中序遍历建树
//left1和right1是后序遍历的范围
//left2和right2是中序遍历的范围
tree createTree(int left1, int right1, int left2, int right2){
//printf("(%d, %d, %d, %d)\n", left1, right1, left2, right2);
if(right1<left1 || right2<left2){
return NULL;
}
tree p = (node*)malloc(sizeof(node));
p->data = postorder[right1];
//printf("%d\n", p->data);
if(left2==right2){ //只有一个结点了
p->lchild = NULL;
p->rchild = NULL;
return p;
}
//寻找中序遍历中根节点的位置
int idx;
for(idx=left2; idx<=right2; idx++){
if(inorder[idx]==postorder[right1]){
break;
}
}
//计算左右子树的个数
int cntLeft = idx-left2;
int cntRight = right2-idx;
p->lchild = createTree(left1, left1+cntLeft-1, left2, idx-1);
p->rchild = createTree(left1+cntLeft, left1+cntLeft+cntRight-1, idx+1, right2);
return p;
}
void levelTraverse(tree root){
int cnt = 0;
tree queue[MAXSIZE];
int st=0; //队头
int ed=0; //队尾
queue[ed++] = root;
while(st!=ed){
tree tmp = queue[st++];
if(tmp->lchild!=NULL){
queue[ed++] = tmp->lchild;
}
if(tmp->rchild!=NULL){
queue[ed++] = tmp->rchild;
}
if(cnt!=0){
printf(" ");
} else {
cnt++;
}
printf("%d", tmp->data);
}
}
int main(){
scanf("%d", &n);
for(int i=0; i<n; i++){
scanf("%d", &postorder[i]);
}
for(int i=0; i<n; i++){
scanf("%d", &inorder[i]);
}
node* root = createTree(0, n-1, 0, n-1);
levelTraverse(root);
return 0;
}