后缀表达式 (2) —— 表达树与后缀表达式的运算

原创 2016年08月30日 16:00:45

后缀表达式的表达树

在上一篇博客 后缀表达式(1)中已经提到过,后缀表达式的优点在于它便于计算机和识别与处理。我们编程解析后缀表达式的过程,其实是生成该表达式的表达树的过程。虽然我们并不一定在代码中显式地把这棵树构造出来,但我们确实隐含地运用了表达树的结构。因此,手工把这棵表达树画出来,对于理解后缀表达式的运算过程非常有用。

这里,我们依然假设运算符都是二元的,这样构造出来的表达树必然是一个二叉树。对于一个给定的后缀表达式,它表达树的根节点是该表达式最外层的运算符。根节点的左右子树分别为该运算符的第一个和第二个运算元。这两个运算元可能是树,也可能是后缀子式对应的表达树。

例. 对于如下后缀式

ab+

其对应的表达树为

        +
       / \
      a   b

例. 考虑一个稍微复杂的后缀式

abc+

首先看到它的最后一个字符是加号+,这说明这个后缀式的最外层运算是加法运算,故而根节点为+。见下图。

   +
  / \

加号之前的字符串abc表示了这个加法运算的两个运算元。

按照后缀式的性质,最后一个字符-一定是属于加法运算的第二个运算元。由于第二个运算元以运算符结尾,所以它也是一个后缀式。 见下图。

   +
  / \
 /   -
    / \

接下来, 字符串abc中包含了减法运算的两个运算元,和加法运算的第一个运算元。根据后缀式的性质,最右边的字符c属于减法运算的第二个运算元,而字符b属于减法运算的第一个运算元。最后a属于加法运算的第一个运算元。见下图。

   +
  / \
 /   -
a   / \
   b   c

注意: 在后缀式的表达树中,每一个运算符对应的是表达树的非叶子节点,而每个字母,对应的是表达树的叶子节点。在构造后缀式的表达树时,我们总是把字符串中的最后一个字符放在表达树中最右边的非满节点下

例. 考虑下面的复杂的例子

abc+defg/+hij

首先最右边的字符是减号,构造根节点如下图,剩下的字符串为abc+defg/+hij

   -
  / \

在字符串abc+defg/+hij中,最右边的字符为减号-,放到根节点下得下图,剩下的字符串为abc+defg/+hij

   -
  / \
    -
   /  \

在字符串abc+defg/+hij中,最右边的字符为乘号,放在最右边的减号下得下图,剩下的字符串为abc+defg/+hij

   -
  / \
    -
   /  \
       *
      / \

将字符串abc+defg/+hij最右边的两个字符ij放在最右边的乘号下得下图。剩下的字符串为abc+defg/+h

   -
  / \
    -
   /  \
       *
      / \
     i   j

接下来,节点i和j是叶子节点,乘号节点已经满了,因此最右边的非满节点为第二层的减号节点。故应该将字符串abc+defg/+h的最后一个字符h放到该节点下。见下图。剩下的字符串为abc+defg/+

   -
  / \
    -
   /  \
  h    *
      / \
     i   j

接下来,唯一的非满节点是根节点。这表示根节点的第二个运算元已经生成完毕。我们将最右边的加号字符放到根节点下,得到下图。剩下的字符串为abc+defg/

     -
    / \
   /   \
  /     \
 +       -
/ \     /  \
       h    *
           / \
          i   j

接下来,唯一非满的节点为根号节点,故将字符串abc+defg/中最右边的字符除号/放在加号节点下得下图。剩下的字符串为abc+defg

     -
    / \
   /   \
  /     \
 +       -
/ \     /  \
  (/)  h    *   注意:这一行的/表示除号。
  / \      / \
          i   j

字符串abc+defg中最后两个字符放在表达树第三层最左边的乘号下得下图。剩余的字符串为abc+def

     -
    / \
   /   \
  /     \
 +       -
/ \     /  \
  (/)  h    *  注意:这一行的/表示除号。
  / \      / \
 *   g    i   j
/ \

将字符串abc+def最右边的子串def依次填进表达树得下图。剩下的字符串为abc+

      -
     / \
    /   \
   /     \
  +       -
 / \     /  \
   (/)  h    *  注意:这一行的/表示除号。
   / \      / \
  *   g    i   j
 / \
d   -
   / \
  e   f

最后得到的表达树为

                -
               / \
              /   \
             /     \
            /       \
           /         \
          /           \
         +             -
        / \           /  \
       /   \         /    \
      /     \       /      \
     /       \     /        \
    /         \   /          \
   +         (/)  h           *  注意:这一行的/表示除号。
  / \        / \              / \
 a   *      *   g            i   j
    / \    / \
   b   c  d   -
             / \
            e   f

后缀表达式的运算

一旦后缀表达式的表达树生成好了,那么后缀表达式的运算可以通过自底向上的方法实现。这里仅以一个简单的例子作为说明。

前面已经介绍过后缀式

abc+

的生成树为

   +
  / \
 /   -
a   / \
   b   c

现在假设

a=9b=7,c=2.

于是表达树变为

   +
  / \
 /   -
9   / \
   7   2

先计算以减号为根节点的子树,即72=5。于是表达树变为

    +
   / \
  9   5

最后结果为14。

版权声明:本文为博主原创文章,转载请注明出处和作者。

相关文章推荐

用栈的方法运算后缀表达式的值

自己写代码的能力比较差,这段代码写了好长时间。 #include #include #include #define EmptyTOS (-1) #define MinStackSize...

中缀表达式变成等价的后缀表达式的算法

理论: (这部分很重要,看明白了,可以写出实现算法)表达式的表示形式有中缀、前缀和后缀3中形式。中缀表达式按操作符的优先级进行计算(后面代码实现只包括+、-、*、/,小括号),即数学运算。 后缀表达式...

数据结构基础之后缀表达式与中缀表达式的相互推导

中缀表达式:把平时用的标准四则运算表达式叫中缀表达式 逆波兰表示:一种不需要括号的后缀表达法
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)