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

2014-11-24 08:06:42 · 作者: · 浏览: 0

Expressions

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


题目大意:

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

解题思路:

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

代码:

#include
   
    
#include
    
      #include
     
       #include
      
        #include
       
         #include
        
          #include
         
           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<
          
           >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; }