zoukankan      html  css  js  c++  java
  • A1086. Tree 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 (<=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

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<stack>
     4 #include<string.h>
     5 using namespace std;
     6 typedef struct NODE{
     7     NODE* left, *right;
     8     int data;
     9 }node;
    10 stack<int> stk;
    11 int pre[31], in[31], N;
    12 node* create(int preL, int preR, int inL, int inR){
    13     if(preL > preR){
    14         return NULL;
    15     }
    16     node *root = new node;
    17     root->data = pre[preL];
    18     int i;
    19     for(i = inL; i <= inR; i++)
    20         if(in[i] == root->data)
    21             break;
    22     int Lnum = i - inL;
    23     root->left = create(preL + 1, preL + Lnum, inL, i - 1);
    24     root->right = create(preL + Lnum + 1, preR, i + 1, inR);
    25     return root;
    26 }
    27 void post(node *tree, int &cnt){
    28     if(tree == NULL)
    29         return;
    30     post(tree->left, cnt);
    31     post(tree->right, cnt);
    32     if(cnt == N - 1)
    33         printf("%d", tree->data);
    34     else{
    35         printf("%d ", tree->data);
    36         cnt++;
    37     }
    38 }
    39 
    40 int main(){
    41     int num, indexPre = 0, indexIn = 0;
    42     char str[5];
    43     scanf("%d", &N);
    44     for(int i = 0; i < 2*N; i++){
    45         scanf("%s", str);
    46         if(strcmp(str, "Push") == 0){
    47             scanf("%d ", &num);
    48             stk.push(num);
    49             pre[indexPre++] = num;
    50         }else{
    51             num = stk.top();
    52             stk.pop();
    53             in[indexIn++] = num;
    54         }
    55     }
    56     node *tree = create(0, N - 1, 0, N - 1);
    57     int cnt = 0;
    58     post(tree, cnt);
    59     cin >> N;
    60     return 0;
    61 }
    View Code

    总结:

    1、中序遍历的非递归实现:不断将非空的左孩子入栈,当左边为空时,弹出一个栈顶元素访问之,并将指针移至他的右子树,继续进行开始时的操作。 在这个过程中,push的特点是不断把遇到的新节点push入栈,因此push的过程就是先序遍历的过程。而pop自然是中序的过程。因此,中序与先序的非递归实现的区别就在于访问节点的时机不同,先序在push时,中序在pop时

    2、因此可以根据题目同时建立一个栈,同步做push和pop操作,先得到先序与中序遍历序列,再按照套路建树。

  • 相关阅读:
    C Language Study
    html学习笔记五
    [CS]C#操作word
    bzoj2502 清理雪道
    Android Studio怎样查看资源或者函数在哪些类中被引用
    jvm载入过程
    poj2513(无向图判欧拉路)
    7 天玩转 ASP.NET MVC — 第 2 天
    从头认识java-18.2 主要的线程机制(7)join
    启动MFC程序的时候报错:0xC0000005: 读取位置 0x00000000 时发生访问冲突
  • 原文地址:https://www.cnblogs.com/zhuqiwei-blog/p/8538979.html
Copyright © 2011-2022 走看看