zoukankan      html  css  js  c++  java
  • PAT甲级——【牛客练习A1004】

    题目描述

    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 }
  • 相关阅读:
    Template(模板)模式
    Android活动(Activity)创建及生命周期
    Android--SharedPreferences数据存储方案
    Adapter适配器模式--图解设计模式
    准时制生产(Just in Time,JIT)
    术语
    制造资源计划(Manufacturing Resource Planning,Mrp II)
    Angualr6表单提交验证并跳转
    Android PDA扫描枪广播接搜条码并使用
    Java统计代码行数
  • 原文地址:https://www.cnblogs.com/zzw1024/p/11158022.html
Copyright © 2011-2022 走看看