题目:http://pta.patest.cn/pta/test/16/exam/4/question/667
PTA - Data Structures and Algorithms (English) - 5-5
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.
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 //即后序遍历树的结果
解法转自:http://www.cnblogs.com/clevercong/p/4177802.html
题目分析:
动态的“添加结点”并遍历过程,不需要建树。
借助“栈”进行树的后续遍历;( times:可由此栈操作判断中当前结点有左子树还是右子树中 )
每次PUSH,times = 1;// PUSH:可看作访问左孩子
每次POP检查栈顶记录的times:
- 如果是1,弹出来变成2压回栈;// POP:可看作由左孩子转到访问右孩子
- 如果是2,则弹出,放入存放结果的vector中,重复这一过程,直到栈顶times为1。// POP:可看作访问根节点
所有PUSH与POP操作执行完毕时,输出vector内的数据和stack中的数据。 注意要处理最后的空格。
注:此方法可推广到n叉树,只需改变times的值即可。
代码:
#include <iostream> #include <stack> #include <vector> using namespace std; typedef struct node { int data; int times; node(int d, int t) :data(d), times(t) {}; } Node; int main() { int n; cin >> n; string cmd; //!PUSH or POP int x; stack<Node> sta; //!栈:用来实现后序遍历 vector<int> vec; //!存放结果 for(int i=0; i<2*n; i++) { cin >> cmd; if(cmd == "Push") { cin >> x; sta.push(Node(x, 1)); } if(cmd == "Pop") { Node node = sta.top(); sta.pop(); if(node.times == 1) //!times==1:弹出来变成2压回栈 { node.times = 2; sta.push(node); } else if(node.times == 2) //!times==2:弹出,放入存放结果的vector中 { vec.push_back(node.data); while(sta.top().times == 2) //!重复这一过程,直到栈顶的times==1 { vec.push_back(sta.top().data); sta.pop(); } if (sta.size() != 0) //!操作结束后栈还不为空,使栈顶的times=2 { sta.top().times=2; } } } } for(unsigned int i=0; i<vec.size(); i++) { cout << vec[i]<< " "; } while(sta.size() != 0) //!PUSH/POP结束后栈中还有元素,直接pop()即可 { cout << sta.top().data; sta.pop(); if(sta.size() != 0) cout << " "; } return 0; }