PAT-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.

题意:给定含n个节点的树,执行Push , Pop 语句后得到的结果为树的中序。另外Push的数字顺序即为树的前序(普通树就是“根左右”顺序建立的)。由此得到树的前序,中序遍历 。

eg(数据见下图):前序结果:1 2 3 4 5 6;    中序结果:3 2 4 1 6 5。

求解后序思路:前序确定根节点,然后到中序数组中找到根节点的位置,至此在中序中可以划分左右子树,递归执行。完成对后序遍历。注意:因为划分时是左右根顺序,刚好符合后序遍历顺序。因此可以用一个vector数组来记录后序元素。

代码:

/**
   @PAT-Tree Traversals Again
*/
#include<bits/stdc++.h>
using namespace std;
vector<int> pre,in,post;
void postorder(int root, int start, int end) {
    if (start>end) return;
    int i = start;
    while (i<end&&in[i] != pre[root]) i++;  //找到根节点在中序中的位置
    postorder(root+1,start,i-1);           //左子树
    /**
       *root+1:根节点的位置(在前序中体现),
       *start:左子树元素的起始位置(在中序数组中体现),
       *i-1:左子树元素的结束位置(在中序数组中体现)
    */
    postorder(root+1+i-start,i+1,end); //右子树
    /**
      *root+1+i-start:
        root+1为左子树的根节点位置,
        i-start:左右子树根节点位置(在中序数组中体现)的差值(差值等于上面找根节点所移动距离)
    */
    post.push_back(pre[root]);    //压入根节点
}
int main() {
    int n;
    scanf("%d",&n);
    stack<int> s;
    for(int i = 0;i<2*n;i++){
        char str[10];
        scanf("%s",str);
        if(strlen(str)==4) {
            int num;
            scanf("%d",&num);
            pre.push_back(num);
            s.push(num);           //压入栈
        } else {
            in.push_back(s.top());
            s.pop();
        }
    }
    postorder(0,0,n-1);
    printf("%d", post[0]);
    for (int i = 1; i < n; i++)
        printf(" %d",post[i]);
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值