[UVA 11234] Expressions (二叉树的建立与层次遍历)

Expressions

题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=14332


题目大意:

  一个表达式,可以用栈来处理,同时可以用队列来处理。现在告诉你用栈处理的表达式顺序,求其用队列表示的顺序? 几种操作数为小写字母,操作符为大写字母。
如输入:
2
xyPzwIM
abcABdefgCDEF
则输出:
wzyxIPM
gfCecbDdAaEBF

解题思路:

  我们知道表达式在计算机中可以用二叉树表示。其中正常的表达式为树的中序遍历,而采用栈来模拟,则为树的后序遍历。如果用队列来表示表达式呢?
  我们不妨把第一组样例的表达式处理成二叉树,然后对比队列的输出,便一目了然了。
  
  我们可以看到,用栈表示为其后序,而用队列表示是其层次遍历的逆序输出。层次为MPIxyzw。
  所以这道题就变成了先建树,然后再层次遍历,最后逆序输出。
  我一开始的做法是,利用栈的后序,可以得到其中序遍历,然后利用中序和后序可以建树。但是由于这个树比较深,所以会爆栈。
  其实利用栈的后序,完全可以直接建树了,因为操作符和操作数分别是大小写字母,可以区分。
  即遇到小写字母就建立一个只有根节点的树,并将该地址入栈。
  遇到大写字母,就建立一个根节点为该大写字母,然后从栈中取出两个地址,分别作为该节点的左右孩子,然后再将该根节点地址入栈
  由于怕栈溢出,所有的栈操作都改为了数组模拟。
 

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<string>
#include<stack>
#include<algorithm>
using namespace std;
char post[10010];
struct tree
{
    char ch;
    tree* lchild;
    tree* rchild;
};
tree* newnode()
{
    tree* u = (tree*) new (tree);
    u->ch = '\0';
    u->lchild = u->rchild = NULL;
    return u;
}
void bfs(tree* root)
{
    char out[10010];
    tree* que[10010] = {NULL};
    int font, rear, k = 0;
    font = 0, rear = 1;
    que[font] = root;
    out[k++] = root->ch;
    while(font < rear)
    {
        tree* tmp;
        tree* next;
        tmp = que[font++];
        if (tmp->lchild != NULL)
        {
            next = tmp->lchild;
            que[rear++] = next;
            out[k++] = next->ch;
        }
        if (tmp->rchild != NULL)
        {
            next = tmp->rchild;
            que[rear++] = next;
            out[k++] = next->ch;
        }
    }
    for (int i = k - 1; i >= 0; i--)
        cout<<out[i];
}
int main ()
{
    int t, i, n;
    cin>>t;
    getchar();
    while(t--)
    {
        gets(post);
        n = strlen(post);
        tree* s[10010];
        int k = 0;
        for (i = 0; i < n; i++)
        {
            if (post[i] <= 'Z') //碰到操作符,从栈中取出两个地址,分别作为左右孩子,然后将其根地址再次入栈
            {
                tree* u = newnode();
                u->ch = post[i];
                u->rchild = s[--k];
                u->lchild = s[--k];
                s[k++] = u;
            }
            else //碰到操作数,将地址其入栈
            {
                tree* u = newnode();
                u->ch = post[i];
                s[k++] = u;
            }
        }
        tree* root = s[--k]; //把树的根节点取出
        bfs(root); //进行层次遍历
        puts("");
        memset(post, 0, sizeof(post));
    }
    return 0;
}





  
  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值