A1086. Tree Traversals Again

An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.


Figure 1

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2N lines follow, each describes a stack operation in the format: "Push X" where X is the index of the node being pushed onto the stack; or "Pop" meaning to pop one node from the stack.

Output Specification:

For each test case, print the postorder traversal sequence of the corresponding tree in one line. A solution is guaranteed to exist. All the numbers must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:

6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop

Sample Output:

3 4 2 6 5 1

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<stack>
 4 #include<string.h>
 5 using namespace std;
 6 typedef struct NODE{
 7     NODE* left, *right;
 8     int data;
 9 }node;
10 stack<int> stk;
11 int pre[31], in[31], N;
12 node* create(int preL, int preR, int inL, int inR){
13     if(preL > preR){
14         return NULL;
15     }
16     node *root = new node;
17     root->data = pre[preL];
18     int i;
19     for(i = inL; i <= inR; i++)
20         if(in[i] == root->data)
21             break;
22     int Lnum = i - inL;
23     root->left = create(preL + 1, preL + Lnum, inL, i - 1);
24     root->right = create(preL + Lnum + 1, preR, i + 1, inR);
25     return root;
26 }
27 void post(node *tree, int &cnt){
28     if(tree == NULL)
29         return;
30     post(tree->left, cnt);
31     post(tree->right, cnt);
32     if(cnt == N - 1)
33         printf("%d", tree->data);
34     else{
35         printf("%d ", tree->data);
36         cnt++;
37     }
38 }
39 
40 int main(){
41     int num, indexPre = 0, indexIn = 0;
42     char str[5];
43     scanf("%d", &N);
44     for(int i = 0; i < 2*N; i++){
45         scanf("%s", str);
46         if(strcmp(str, "Push") == 0){
47             scanf("%d ", &num);
48             stk.push(num);
49             pre[indexPre++] = num;
50         }else{
51             num = stk.top();
52             stk.pop();
53             in[indexIn++] = num;
54         }
55     }
56     node *tree = create(0, N - 1, 0, N - 1);
57     int cnt = 0;
58     post(tree, cnt);
59     cin >> N;
60     return 0;
61 }
View Code

 

总结:

1、中序遍历的非递归实现:不断将非空的左孩子入栈,当左边为空时,弹出一个栈顶元素访问之,并将指针移至他的右子树,继续进行开始时的操作。 在这个过程中,push的特点是不断把遇到的新节点push入栈,因此push的过程就是先序遍历的过程。而pop自然是中序的过程。因此,中序与先序的非递归实现的区别就在于访问节点的时机不同,先序在push时,中序在pop时

2、因此可以根据题目同时建立一个栈,同步做push和pop操作,先得到先序与中序遍历序列,再按照套路建树。

posted @ 2018-02-08 13:56  ZHUQW  阅读(163)  评论(0编辑  收藏  举报