03-树3 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.
    864046-20170426112210178-1915779089.png

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

分析思路

  • Push操作刚好是树的前序遍历过程;Pop操作刚好是树的中序遍历操作

AC代码

/*!
 * \file 03-树3 Tree Traversals Again.cpp
 *
 * \author ranjiewen
 * \date 2017/04/25 23:51
 *
 * 
 */

#include <iostream>
#include <cstdio>
#include <stack>
#include <string>

using namespace std;

#define MaxSive 30
#define OK 0
#define ERROR -1

int preOrder[MaxSive];
int inOrder[MaxSive];
int postOrder[MaxSive];

void postOrderTraversal(int preNum,int inNum,int postNum,int Num);

int main()
{
    stack<int> s;
    int N; //树的结点数
    cin >> N;
    string str;
    int data;
    int preNum = 0, inNum = 0, postNum = 0;
    for (int i = 0; i < N * 2;i++)  //push+pop=N*2 
    {
        cin >> str;
        if (str=="Push") //Push为前序序列
        {
            cin >> data;
            preOrder[preNum++] = data;
            s.push(data);
        }
        else  //Pop为中序序列
        {
            inOrder[inNum++] = s.top();
            s.pop();  //移除栈顶元素(不会返回栈顶元素的值)
        }
    }

    postOrderTraversal(0,0,0,N); //每棵子树前,中,后序数组的开始下标,N为子树的结点个数

    for (int i = 0; i < N;i++)  //输出后序遍历序列
    {
        if (i==0)   //输出格式控制
        {
            printf("%d", postOrder[i]);
        }
        else
        {
            printf(" %d", postOrder[i]);
        }
    }
    printf("\n");

    return 0;
}

void postOrderTraversal(int preNum, int inNum, int postNum, int Num)
{
    if (Num==0)
    {
        return;
    }
    if (Num==1)
    {
        postOrder[postNum] = preOrder[preNum];
        return;
    }

    int L=0, R=0; //递归左右子树的结点个数
    int root = preOrder[preNum]; //先序遍历的第一个节点为根节点
    postOrder[postNum + Num - 1] = root; //填后序遍历的坑

    for (int i = 0; i < Num;i++)
    {
        if (inOrder[i+inNum] == root)//不要掉了preNum //在中序遍历中找到根节点,分为左右子树递归
        {
            L = i;  //左子树结点个数
            break;
        }
    }
    R = Num- L - 1; //右子树结点个数
    postOrderTraversal(preNum+1,inNum,postNum,L);
    postOrderTraversal(preNum + L + 1, inNum + L + 1, postNum + L, R); //右子树递归调用,注意开始下标

}

Reference

题目来源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值