PAT (Advanced Level) Practice 1020

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;
}
 

猜你喜欢

转载自blog.csdn.net/a568283992/article/details/82078219
今日推荐