[PTA] 7-5 Tree Traversals Again

题目详情
题目分析:

  • 这道题的关键是如何重建树
  • 由图可知,每一次push就是向下建树
  • 每一次pop结束后一次push都是创建右子树
  • 每一次push之后的连续push都是创建左子树
  • 每一次push后的第一次pop都是在图中相当于拐一个弯,但cur(即当前节点的指针)所指向的节点没有变
  • 每一次pop之后的连续pop都是向上回溯,我们每一个节点都记录它上一个节点是哪个,此外每一个节点用visit来记录是否已经被pop过了,向上回溯的时候一直要回溯到没有被pop的节点,一旦被访问就将这个节点的visit标记为1,表示已经访问过了
  • n记录一共几个数字
  • PopTime记录一共pop了多少次,当PopTime == n是结束输入
  • PushTime记录是否是第一次push
  • curPop记录是否是第一次pop
  • num记录当前输入的数字
  • times记录是否为第一次输出数字,输出格式要符合题意
#include <iostream>
#include <string>
using namespace std;
int n, PopTime, num, PushTime, curPop, times;
string str;
struct Tree
{
    Tree *left, *right, *last;
    int val, visit;
};
Tree *root, *cur;
void postTraversal(Tree *now)
{
    if (now->left != NULL)
        postTraversal(now->left);
    if (now->right != NULL)
        postTraversal(now->right);
    if (times == 0)
        cout << now->val, times++;//特判,第一个不输出空格
    else
        cout << " " << now->val;
}
int main()
{
    cin >> n;
    while (PopTime != n)
    {
        cin >> str;
        if (str == "Pop")
        {
            PopTime++, PushTime = 0;
            if (curPop)
                while (cur->visit != 0)
                    cur = cur->last;//一直回溯到没有被pop的节点
            cur->visit = 1;//一旦跳出while循环,就把这个节点标记为已经访问过了,如果curPop等于零直接执行此步骤,说明这是push后第一次pop,将当前节点设置为已经访问过了
            curPop++;//此时pop次数加一
        }
        if (str == "Push")
        {
            cin >> num;
            curPop = 0;//一旦输入遇到push,此时pop归零重新计数,等待下一次遇到第一个pop
            Tree *now = new Tree;
            now->val = num;
            now->left = NULL;
            now->right = NULL;
            now->visit = 0;
            if (root == NULL)
            {
                now->last = NULL;
                cur = root = now;
                PushTime++;
                continue;
            }
            now->last = cur;
            if (!PushTime)
                cur->right = now;//如果pushtime为零说明这是上一次pop之后,第一次push,此时创建的节点应该成为当前节点的右节点
            else
                cur->left = now;//如果pushtime不为零,说明上一个操作也是push,此时将节点创建在当前节点的左节点
            cur = now;//移动当前指针,将它指向新创建的节点
            PushTime++;//push次数加一
        }
    }
    postTraversal(root);//递归输出后序遍历
}

References

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值