通过前序遍历建立树——PTA——03-树3 Tree Traversals Again (25分)

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

分析

pop相当于说中序遍历,而push相当于前序遍历,我们用两个数组来记录中序遍历与前序遍历的答案,也就是pre[]和in[] 递归函数是两个数组的最小索引和最大索引
然后pre的最小索引的元素a一定是结点,然后a在in左边的全是左子树,右边的全是右子树,再这样递归下去,算法也就变成了不停找根结点的,但是这里需要注意的是递归的时候,前序最好都写成中序的相对位置

int build(int L1 ,int R1,int L2,int R2)
{
    if(L2 > R2||L1>R1)
        return null;

        int root = pre[L1];
        T[root].data = pre[L1];

        int index = v[pre[L1]]; //中序遍历的位置
        //cout<<T[root].data<<endl;
        T[root].L = build(L1+1,L1+index-L2,L2,index-1);
        T[root].R = build(L1+index+1-L2,R1,index+1,R2);
        
        return root;
    

}

完整代码

#include<iostream>
#include<stack>
#include<cstdio>
#include<cstring>
#include<string.h>
const int MAXN=100000;
const int null=-1;
using namespace std;

stack<int> s;
int pre[MAXN],in[MAXN],v[MAXN],pos[MAXN];
int precount=0,incount=0;
int n;

typedef struct TR{
    int data;
    int L;
    int R;
}TR;

TR T[MAXN];
bool f=1;

int build(int L1 ,int R1,int L2,int R2)
{
    if(L2 > R2||L1>R1)
        return null;

        int root = pre[L1];
        T[root].data = pre[L1];

        int index = v[pre[L1]]; //中序遍历的位置
        //cout<<T[root].data<<endl;
        T[root].L = build(L1+1,L1+index-L2,L2,index-1);
        T[root].R = build(L1+index+1-L2,R1,index+1,R2);
        
        return root;
    

}


void dfs(int root)
{
    if(T[root].L!=null)
        dfs(T[root].L);

    if(T[root].R!=null)
        dfs(T[root].R);

    if(f)
    {
        cout<<T[root].data;
        f=0;
    }

    else
        cout<<" "<<T[root].data;
}


int main()
{
    string cmd;
    cin>>n;
    for (int i = 0; i < 2*n; ++i)
    {
        cin>>cmd;
        if(cmd[1]=='u')
        {
            int a;
            cin>>a;
            s.push(a);
            pre[precount++]=a;  //储存先序遍历
        }

        if(cmd[1]=='o')
        {
            int temp = s.top();
            s.pop();
            v[temp] = incount;      //储存中序遍历的索引
            in[incount++]=temp;     //储存中序遍历
        }

    }


    
    //接下来是建树过程
    build(0,n-1,0,n-1);
    dfs(pre[0]);




    return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值