题目描述
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
输入描述:
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.
输出描述:
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.
输入例子:
6 Push 1 Push 2 Push 3 Pop Pop Push 4 Pop Pop Push 5 Push 6 Pop Pop
输出例子:
3 4 2 6 5 1
解题思路:
根据题意可知, 栈的数据压入为二叉树的前序,栈的弹出为中序,求后序遍历
一般是通过前序、中序来构造二叉树,然后在遍历出后序遍历即可
版本一:
该版本的缺陷是,当出现相同数字时,无法在中序中确定谁是根节点!
1 #include <iostream> 2 #include <stack> 3 #include <vector> 4 5 using namespace std; 6 7 struct Node 8 { 9 int val; 10 Node* l; 11 Node* r; 12 Node(int a = -1) :val(a), l(nullptr), r(nullptr) {} 13 14 }; 15 16 //通过前序、中序构造二叉树 17 Node* Create(const vector<int>dataPre, const vector<int>dataOrd, 18 int preL, int preR, int ordL, int ordR)//数据源,前序的左右边界,中序的左右边界 19 { 20 if (preL < preR) 21 return nullptr; 22 Node* root = new Node(); 23 root->val = dataPre[preL];//根节点 24 int k = ordL; 25 while (dataOrd[k] != dataPre[preL]) 26 ++k; 27 k = k - ordL;//左子树个数 28 root->l = Create(dataPre, dataOrd, preL + 1, preL + k, ordL, ordL + k - 1);//构造左子树 29 root->r = Create(dataPre, dataOrd, preL + k + 1, preR, ordL + k + 1, ordR);//构造右子树 30 return root; 31 } 32 33 //后序遍历 34 void LastTravle(vector<int>&res, Node* root) 35 { 36 if (root == nullptr) 37 return; 38 LastTravle(res, root->l); 39 LastTravle(res, root->r); 40 res.push_back(root->val); 41 } 42 43 44 int main() 45 { 46 int N; 47 cin >> N; 48 N = 2 * N; 49 stack<int>data; 50 vector<int>dataPre, dataOrd; 51 while (N--) 52 { 53 string str; 54 cin >> str; 55 if (str == "Push") 56 { 57 int a; 58 cin >> a; 59 dataPre.push_back(a); 60 data.push(a); 61 } 62 else 63 { 64 dataOrd.push_back(data.top()); 65 data.pop(); 66 } 67 } 68 Node* root; 69 root = Create(dataPre, dataOrd, 0, dataPre.size() - 1, 0, dataOrd.size() - 1); 70 vector<int>res; 71 LastTravle(res, root); 72 for (int i = 0; i < res.size() - 1; ++i) 73 cout << res[i] << " "; 74 cout << res[res.size() - 1] << endl; 75 }
版本二:
使用key,避免了重复数字的尴尬,也不需真正构造一颗二叉树
1 #include <vector> 2 #include <stack> 3 #include <string> 4 using namespace std; 5 vector<int> pre, in, post, value; 6 void postorder(int root, int start, int end) { 7 if (start > end) return; 8 int i = start; 9 while (i < end && in[i] != pre[root]) i++; 10 postorder(root + 1, start, i - 1); 11 postorder(root + 1 + i - start, i + 1, end); 12 post.push_back(pre[root]); 13 } 14 int main() { 15 int n; 16 cin >> n; 17 n = 2 * n; 18 stack<int> s; 19 int key = 0; 20 while (n--) { 21 string str; 22 cin >> str; 23 if (str.length() == 4) { 24 int num; 25 cin >> num; 26 value.push_back(num); 27 pre.push_back(key); 28 s.push(key++); 29 } 30 else { 31 in.push_back(s.top()); 32 s.pop(); 33 } 34 } 35 postorder(0, 0, pre.size() - 1); 36 printf("%d", value[post[0]]); 37 for (int i = 1; i < n; i++) 38 printf(" %d", value[post[i]]); 39 return 0; 40 }