03-树3 Tree Traversals Again (25分)

来源:互联网 发布:美国 海洋法公约 知乎 编辑:程序博客网 时间:2024/05/18 02:14

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
刚开始时,前序遍历的第一个元素1肯定是该二叉树的根节点,因此为postOrder的最后一个元素,在中序遍历中1前面的元素肯定为该颗二叉树的左子树在1右边的元素肯定为该二叉树的右子树,因此,递归的求解该二叉树。
2
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;}
0 0
原创粉丝点击