1020 Tree Traversals(25 分)
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
题意:就是根据后序遍历和中序遍历,来写出其层次遍历。
思路:我的想法就是,模拟人工写法,构造出这颗树,然后再使用队列模拟层次遍历即可。
#include<cstdio>
#include<cstdlib>
#include<stack>
#include<queue>
using namespace std;
typedef struct Node{
int val;
struct Node *left, *right;
}*Tree, Node;
#define N 35
int postOrder[N];//后序数组
int inOrder[N];//中序数组
bool visited[N];//记录当前是否已经被遍历过
int tag[N];//记录当前中序已经遍历的角标对应的次序
int n;
//查询当前值在中序中的角标
int searchIndex(int val){
for(int i = 0;i < n;i++){
if(val == inOrder[i])
return i;
}
return -1;
}
stack<Node *> s;
//根据值查找这个节点在二叉树的位置,返回这个节点指针
Node * findRoot(Tree &t, int val){
s.push(t);
while(!s.empty()){
Node *p = s.top();
s.pop();
if(p->val == val){
return p;
}else{
if(p->left){
s.push(p->left);
}
if(p->right){
s.push(p->right);
}
}
}
return NULL;
}
void calTree(Tree &t){
for(int i = n - 1;i >= 0;i--){
int index = searchIndex(postOrder[i]);//获取当前值在中序中的角标
visited[index] = true;//当前角标置为true
tag[index] = n - i;//当前中序角标的次序
if(i == n - 1){//如果第一次遍历,头就是根
t = (Node *)malloc(sizeof(Node));
t->val = postOrder[i];
t->left = t->right = NULL;
}else{
int l, r;
l = r = -1;
for(int j = index + 1;j < n;j++){//根据index向右遍历,直到遇到已经visit的点。
if(visited[j]){
r = j;
break;
}
}
for(int j = index - 1;j >=0;j--){//根据index向左遍历,直到遇到已经visit的点。
if(visited[j]){
l = j;
break;
}
}
int root = -1;
if(l == -1){
root = inOrder[r];
} else if(r == -1){
root = inOrder[l];
}else{
if(tag[l] > tag[r]){//判断当前需要插入的节点两侧中的其中一个更大的tag的节点即为其父Node
root = inOrder[l];
}else if(tag[l] < tag[r]){
root = inOrder[r];
}
}
Node *p = findRoot(t, root);//查找出此Node所在位置
Node *q = (Node *)malloc(sizeof(Node));
q->val = postOrder[i];
q->left = q->right = NULL;
if(tag[l] > tag[r]){
p->right = q;
}else{
p->left = q;
}
}
}
}
queue<Node *> q;
void levelTreaversal(Tree t){//层次遍历
Node *p = t;
q.push(p);
while(!q.empty()){
p = q.front();
q.pop();
if(p->left){
q.push(p->left);
}
if(p->right){
q.push(p->right);
}
if(q.empty()){
printf("%d", p->val);
}else{
printf("%d ", p->val);
}
}
}
int main(){
Tree t;
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]);
}
calTree(t);
levelTreaversal(t);
return 0;
}