03-树3 Tree Traversals Again (25分)
2015-10-20 16:30
645 查看
03-树3 Tree Traversals Again (25分)
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
solution:如果对二叉树的遍历非递归实现有很好理解的话,那么这里理解起来就不是很大的难度,在输入格式中Push的过程就是二叉树前序遍历的结果,而Pop的过程及为二叉树的中序遍历的结果。如果理解了这两个操作,那么题目的意思就变成了已知二叉树的前序遍历和中序遍历求二叉树的后序遍历。由于前序遍历首先访问的是根节点,中序遍历首先访问的是左子树,而后序遍历最后才访问根节点。因此,前序遍历中第一个元素为后序遍历的最后一个元素,在中序遍历中根节点左边的为左子树的节点,右边为右子树的节点。所以需要递归的求解这个问题。
对于Sample的求解结果为:
刚开始时,前序遍历的第一个元素1肯定是该二叉树的根节点,因此为postOrder的最后一个元素,在中序遍历中1前面的元素肯定为该颗二叉树的左子树在1右边的元素肯定为该二叉树的右子树,因此,递归的求解该二叉树。
code :
#include<iostream> #include<string> #include<vector> #include<stack> using namespace std; // 给定前序遍历和中序遍历,求出二叉树的后序遍历 void getPostOrder(vector<int> preOrder, int preL, vector<int> inOrder, int inL, vector<int> &postOrder, int postL, int n) { if (n == 0) return ; if (n == 1) { postOrder[postL] = preOrder[preL]; return ; } auto root = preOrder[preL]; postOrder[postL + n - 1] = root; //在中序遍历数组上找出root的位置 int i = 0; while (i < n) { if (inOrder[inL + i] == root) break; ++i; } // 计算出root节点左右子树节点的个数 int L = i, R = n - i - 1; // 递归的进行求解 getPostOrder(preOrder, preL + 1, inOrder, inL, postOrder, postL, L); getPostOrder(preOrder, preL + L + 1, inOrder, inL + L + 1, postOrder, postL + L, R); } vector<vector<int>> getOrder(int N) { vector<int> preOrder(N, 0); vector<int> inOrder(N, 0); stack<int> st; int preL = 0, inL = 0; for (int i = 0; i < 2*N; ++i) { string str; int tmp; cin >> str; if (str == "Push") { cin >> tmp; preOrder[preL++] = tmp; st.push(tmp); } else if (str == "Pop") { inOrder[inL++] = st.top(); st.pop(); } } return {preOrder, inOrder}; } int main() { int N; cin >> N; auto res = getOrder(N); vector<int> postOrder(N, 0); getPostOrder(res[0], 0, res[1], 0, postOrder, 0, N); int i = 0; for (; i < N-1; ++i) { cout << postOrder[i] << " "; } cout << postOrder[i] << endl; return 0; }
相关文章推荐
- CC2541 AirSync(2)——广播包
- Cordys 不同 containner 利用 WebService 调用数据
- could not find the main class,program will exit
- Container With Most Water - Leetcode
- [转] 出现( linker command failed with exit code 1)错误总结
- HDOJ 2473 Junk-Mail Filter(并查集集合删点+虚拟父节点)
- RAC Wait Event: gcs log flush sync
- 慎用ArrayList的contains方法,使用HashSet的contains方法代替
- 传统存储系统发展史调研
- 出现( linker command failed with exit code 1)错误总结
- ls --color的使用
- rails中的正则表达式的相关错误提示
- HDU 3487 Play with Chain [splay]
- Email-Ext Plugin install ------ Jenkins Plugins
- BitLocker Repair Tool - Recover Drive in Windows 7 and 8
- Leetcode Paint House
- cordys Service containner ,service group, dataBase, interface 理解
- Tsinghua OJ:列车调度(Train)
- int main(int argc,char* argv[])详解
- QPainter画图