1086. Tree Traversals Again (25)


1086. Tree Traversals Again (25)
时间限制
200 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

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

提交代码


//这道题在看陈越老师的数据结构时候已经做过了,现在又做了一遍,感觉也是不同了,这次对树的遍历又有了更深的理解,这次栈也没用,

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<stack>
#include<algorithm>
using namespace std;
const int maxn=1000007;
typedef long long ll;
template<class T>inline T read(T&x)
{
    char c;
    while((c=getchar())<=32);
    bool f=false;
    if(c=='-')f=true,c=getchar();
    for(x=0; c>32; c=getchar())x=x*10+c-'0';
    if(f)x=-x;
    return x;
}
template<class T>inline void write(T x)
{
    if(x<0)putchar('-');
    else if(x<10)putchar(x+'0');
    else write(x/10),putchar(x%10+'0');
}
template<class T>inline void writeln(T x)
{
    write(x);
    puts("");
}
//--------IO template--------------------
#define lson (root<<1)//左儿子
#define rson ((root<<1)+1)//右儿子
int a[maxn];//存树的节点
bool vis[maxn];//标记节点是否访问过,因为树在遍历时回溯的时候会用到
int first=1;
void post(int root)
{
    if(a[lson]!=-1)post(lson);
    if(a[rson]!=-1)post(rson);
    if(first)printf("%d",a[root]),first=0;
    else printf(" %d",a[root]);
}
int main()
{
    int n,m,i,j,k,t,x;
    read(n);
    m=n<<1;
    memset(a,-1,sizeof(a));
    char op[5];
    int root=1;
    int ok=0;
    for(i=0;i<m;i++)
    {
        scanf("%s",op);
        if(strcmp(op,"Push")==0)
        {
            read(x);
            if(a[root]!=-1)//是回溯的回来访问的,这时读入的节点必然是这个节点的右儿子
            {
                root=rson;//找到有儿子
                a[root]=x;//赋值
                root=lson;//root更新到左儿子,因为输入的时候先序
            }
            else //不是回溯访问的 ,那么就是第一次访问的,所以这个时候节点的值就是他
            {
                a[root]=x;//节点赋值
                root=lson;//root更新到左儿子

            }
        }
        else
        {
            root/=2;//pop就是回溯,所以回到父亲的节点
            x=a[root];

            while(vis[x])//判断是不是已经访问过了,如果访问过了,那么还要继续回溯到第一个没有访问的节点,这个由样例的4到1,而不是4再到2了
            {
                root/=2;
                x=a[root];
            }
            if(!vis[x])vis[x]=1;//标记访问过的
        }
    }
    post(1);//后序遍历 ,比较简单了,直接递归
    printf("\n");
    return 0;
}



















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值