• 【树】7-5Tree Traversals Again


    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

    Input Specification:

    Each input file contains one test case. For each case, the first line contains a positive integer N (≤) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2 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

    思路:

    • 通过观察可知入栈顺序即先序遍历,出栈顺序即中序遍历,所以在得知先序和中序遍历的基础上还原树,然后对该树进行后序遍历。
    • 其中,为了得到先序(中序)结果,对每一条命令进行判断,如果第二个字符是“u”说明是“push”,然后从第五个位置开始截取就可获得数字,同时将该数字入栈;否则是“pop”,将栈中的数字出栈。
    • 在得到先序和中序序列之后,从前往后遍历先序序列,每次从中序序列中找到左右子树的范围,使用left和right标记,进行递归,如果left!=right,说明当前结点不是叶子结点,继续递归左右子树;如果left==right,说明该结点是叶子结点。
    • 注意,其中的两个变量cur和printtag必须设成全局变量,因为使用该变量的函数中有递归函数,如果cur设成局部变量会发生段错误;如果printtag设成局部变量,会发生输出格式错误。

    解题思路和代码参考https://blog.csdn.net/xyt8023y/article/details/47443489

     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <vector>
     4 #include <stack>
     5 #include <string>
     6 #include <sstream>
     7 using namespace std;
     8 
     9 //分别存储先序序列和中序序列
    10 vector<int>preorder;
    11 vector<int>inorder;
    12 
    13 typedef struct TreeNode* Node;
    14 struct TreeNode
    15 {
    16     int num;
    17     Node left;
    18     Node right;
    19 };
    20 
    21 //根据结点值在中序序列中寻找根结点的下标位置
    22 int FindRootIndex(int rootnum) {
    23     for (unsigned int i = 0; i < inorder.size(); i++) {
    24         if (inorder[i] == rootnum)
    25             return i;
    26     }
    27     return -1;
    28 }
    29 
    30 //通过给出中序序列中左右子树的范围建树
    31 int cur;//定义遍历preorder的变量
    32 Node CreateTree(int left, int right) {
    33     //int cur = 0;
    34     if (left > right)
    35         return NULL;
    36     int rootnum = preorder[cur];
    37     cur++;
    38     int rootIndex = FindRootIndex(rootnum);
    39     //建立该根结点
    40     Node T = (Node)malloc(sizeof(TreeNode));
    41     T->num = rootnum;
    42     T->left = NULL;
    43     T->right = NULL;
    44     if (left != right) {
    45         T->left = CreateTree(left, rootIndex - 1);
    46         T->right = CreateTree(rootIndex + 1, right);
    47     }
    48     return T;
    49 }
    50 
    51 
    52 //后序遍历
    53 int printtag = 0;
    54 void PostTraver(Node T) {
    55     //int printtag = 0;
    56     if (T) {
    57         PostTraver(T->left);
    58         PostTraver(T->right);
    59         if (!printtag) {
    60             cout << T->num;
    61             printtag = 1;
    62         }
    63         else
    64             cout << " " << T->num;
    65     }
    66 }
    67 
    68 int main() {
    69     int n;
    70     stack<int>s;
    71     cin >> n;
    72     getchar();
    73     for (int i = 0; i < n*2; i++) {
    74         string str;
    75         getline(cin, str);
    76 
    77         if (str[1] == 'u') {
    78             int num = stoi(str.substr(5));
    79             preorder.push_back(num);
    80             s.push(num);
    81         }
    82         else {
    83             int num = s.top();
    84             s.pop();
    85             inorder.push_back(num);
    86         }
    87     }
    88     Node T = CreateTree(0,inorder.size()-1);
    89     PostTraver(T);
    90     return 0;
    91 }
  • 相关阅读:
    NSString的几种常用方法
    ios页面间传递参数四种方式
    ios category类别的使用
    iOS: 枚举类型 enum,NS_ENUM,NS_OPTIONS
    IOS导航栏的使用方法
    报错:Expected one result (or null) to be returned by selectOne(), but found: 6
    Spring小知识
    spring动态代理
    登录和注册功能思路
    sql语句实例练习
  • 原文地址:https://www.cnblogs.com/PennyXia/p/12601659.html
Copyright © 2020-2023  润新知