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

本文深入探讨后缀表达式的表达树构造,解释如何通过后缀表达式生成表达树,并详细展示了从后缀表达式到运算树的转换过程,以及如何进行后缀表达式的运算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

后缀表达式的表达树

在上一篇博客 后缀表达式(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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值