在平时中我们接触最多的就是中缀表达式,如2+3*5+6。这种操作符位于操作数中间的就是中缀表达式。但是这种表达式的结构,需要使用树结构来表达,一旦表达式的结构复杂,树就会很庞大,所以相应操作的时间复杂度和空间复杂度都会很高。因此就会想着要将这种非线性的存储转换为线性的存储方式。这个存储结构就是栈。
用栈将中缀表达式转化为后缀表达式。后缀表达式也常被称为逆波兰表达式。
如何将中缀表达式转换为后缀表达式:
在这里我们需要借助栈结构,一个表达式中包含了这样几个元素:操作数,操作符,括号。我们对这几个元素在栈中的操作顺序做出了一些约束,满足这些约束进行操作,我们就可以将一个中缀表达式转化为后缀表达式:
1.对于操作数直接输出
2.对于左括号,首先将其压栈,然后将括号里的内容入栈直到遇到右括号,将所有元素出栈,有一点需要注意,括号有入栈和出栈的操作,但是并不会输出。也就是说在后缀表达式中是没有括号的存在。
3.对于操作符来说,因为有优先级的存在,当我们看到一个操作符时,并不能决定是不是先要计算它,直到我们看到它后面的操作符,让后来的操作符和它比一比,才知道先要做哪个运算。所以对于操作符来说我们不是立即输出,而是先将其压入栈,然后等下一个操作符到来,新的操作符来了之后呢,又有下面几种情况:
a.如果新来的操作符的优先级大于栈顶的操作符的优先级,那么就先将新来的元素压入栈中
b.如果新来的操作符的优先级小于等于栈顶的操作符的优先级,就让栈顶的符号出栈输出
4.就这样直到所有的栈元素都出栈输出为止。就得到后缀表达式
可能上面的文字描述不容易理解,下面这里我给出一个例子:如2*(9+6/3-5)+4进行说明
首先画出一个栈结构,2是中缀表达式的第一个元素,对于操作数是直接输出,所以第一个输出的是2
中缀表达式的第二个元素是*,这是一个操作符,对于操作符,由于优先级我们无法判断是不是先要计算它,所以按照上面的
原则,我们先将其压入栈中。
接下来中缀表达式的第二个元素是(,这是一个左括号,对于括号其优先级最高,我们先将其压入栈中。并把括号中接下来
的元素都入栈。因此9入栈出栈输出,+入栈,6入栈出栈输出,又来了一个/号,/的优先级大于此时的栈顶符号+所以/先入栈
3进栈出栈输出,接下来是-,此时-号的优先级低于/,所以/出栈输出,-又要和+的优先级进行比较,+的优先级等于-号,所以+号终于可以出栈输出了,-进栈,5进栈出栈输出,这时候终于遇到了,-出栈输出),括号里面的都出栈输出后,继续遇到了+号,+号的优先级小于*,*出栈输出,+进栈,4进栈出栈输出,最后+出栈。这样栈里的所有元素全部输出,按照输出顺利得到的序列就是后缀表达式。
所以对应的后缀表达式为:2963/+5-*4+