PTA 5-5 Tree Traversals Again (25) - 树 - 二叉树及其遍历

题目: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的值即可。

image     imageimage       image……

代码:

#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;
}
posted @ 2015-09-14 09:42  claremz  阅读(1108)  评论(0编辑  收藏  举报