26

长话短说,我的讲师很垃圾,通过投影仪向我们展示了前缀堆栈的中缀,他的大阴影挡住了一切,所以我错过了重要的东西

他指的是push和pop,push = 0 pop = x

他举了一个例子,但我根本看不出他是如何得到答案的,

2*3/(2-1)+5*(4-1)

第 1 步反向: )1-4(*5+)1-2(/3*2好的,我可以看到

然后他继续写 x 和 o 的操作,我完全迷失了

回答14-5*12-32*/+然后再次反转得到+/*23-21*5-41

如果有人可以向我解释推式弹出以便我能理解,我会非常感激,我在网上看过但我发现的很多东西似乎比这更重要,所以我真的需要先在这里了解一下

4

9 回答 9

113

希望这将帮助您可视化堆栈,以及它是如何工作的。

空栈:

|     |
|     |
|     |
-------

推后A,你得到:

|     |
|     |
|  A  |
-------

推后B,你得到:

|     |
|  B  |
|  A  |
-------

弹出后,您将获得:

|     |
|     |
|  A  |
-------

推后C,你得到:

|     |
|  C  |
|  A  |
-------

弹出后,您将获得:

|     |
|     |
|  A  |
-------

弹出后,您将获得:

|     |
|     |
|     |
-------
于 2010-09-29T19:53:30.630 回答
13

Oren A发布的步枪夹类比非常好,但我会尝试另一个,并尝试预测教练试图传达的内容。

顾名思义,堆栈是“事物”的排列,具有:

  • 在顶上
  • 一个底
  • 顶部和底部之间的排序(例如,从顶部开始的第二个,从底部开始的第三个)。

(把它想象成你桌上的一摞书,你只能从上面拿东西)

将某些东西推入堆栈意味着“将其放在顶部”。从堆栈中弹出一些东西意味着“从堆栈中取出顶部的'东西'”。

一个简单的用法是颠倒单词的顺序。假设我想反转这个词:“爆米花”。我从左到右推动每个字母(所有 7 个字母),然后弹出 7 个字母,它们将以相反的顺序结束。看起来这就是他对这些表情所做的事情。

推(p) 推(o) 推(p) 推(c) 推(o) 推(r) 推(n)

压入整个单词后,堆栈看起来像:

   |  n   |  <- top
   |  r   |
   |  o   |
   |  c   |
   |  p   |
   |  o   |
   |  p   |  <- bottom (first "thing" pushed on an empty stack)
    ======

当我 pop() 七次时,我按以下顺序得到字母:

n,r,o,c,p,o,p

在教授堆栈时,中缀/后缀/前缀的转换是计算机科学中的一个病态示例:

中缀到后缀的转换。

后修复转换为中缀表达式非常简单:

(从左到右扫描表达式)

  1. 对于每个数字(操作数),将其压入堆栈。
  2. 每次遇到运算符 (+,-,/,*) 从堆栈中弹出两次并将运算符放在它们之间。将其推入堆栈:

因此,如果我们有 53+2*,我们可以通过以下步骤将其转换为中缀:

  1. 按 5。
  2. 按 3。
  3. 遇到+:pop 3,pop 5,push 5+3入栈(与5和3的顺序一致)
  4. 按 2。
  5. 遇到 *:pop 2,pop (5+3),push (2 * (5+3))。

*当您到达表达式的末尾时,如果它的格式正确,您的堆栈应该只包含一项。

通过引入“x”和“o”,他可能一直将它们用作中缀表达式的左右操作数的临时持有者:x + o、x - o 等(或 x、o 的顺序颠倒)。

维基百科上也有一篇很好的文章。我已经将我的答案作为一个 wiki 留下,以防我搞砸了表达式的任何顺序。

于 2010-09-29T20:22:33.480 回答
11

从中缀表达式到前缀表达式的算法是:

-reverse input

TOS = top of stack
If next symbol is:
 - an operand -> output it
 - an operator ->
        while TOS is an operator of higher priority -> pop and output TOS
        push symbol
 - a closing parenthesis -> push it
 - an opening parenthesis -> pop and output TOS until TOS is matching
        parenthesis, then pop and discard TOS.

-reverse output

因此,您的示例类似于(x PUSH,o POP):

2*3/(2-1)+5*(4-1)
)1-4(*5+)1-2(/3*2

Next
Symbol  Stack           Output
)       x )
1         )             1
-       x )-            1
4         )-            14
(       o )             14-
        o               14-
*       x *             14-
5         *             14-5
+       o               14-5*
        x +             14-5*
)       x +)            14-5*
1         +)            14-5*1
-       x +)-           14-5*1
2         +)-           14-5*12
(       o +)            14-5*12-
        o +             14-5*12-
/       x +/            14-5*12-
3         +/            14-5*12-3
*       x +/*           14-5*12-3
2         +/*           14-5*12-32
        o +/            14-5*12-32*
        o +             14-5*12-32*/
        o               14-5*12-32*/+

+/*23-21*5-41
于 2010-09-29T20:33:18.990 回答
4

堆栈是一种 LIFO(后进先出)数据结构。推送和弹出操作很简单。Push 将一些东西放在堆栈上,pop 取出一些东西。您放在顶部,然后取下顶部,以保持 LIFO 顺序。

编辑——从先进先出修正为后进先出。捂脸!

为了说明,你从一个空白堆栈开始

|

然后你按'x'

| 'X'

然后你按'y'

| 'x''y'

然后你弹出

| 'X'

于 2010-09-29T19:34:00.580 回答
3

好的。正如其他回答者解释的那样,堆栈是一种后进先出的数据结构。您可以使用 Push 操作将元素添加到堆栈顶部。您可以使用 Pop 操作从顶部取出一个元素。元素的删除顺序与它们插入的顺序相反(因此后进先出)。例如,如果您按该顺序推送元素 1、2、3,则数字 3 将位于堆栈顶部。Pop 操作将删除它(它是最后一个)并将 2 留在堆栈顶部。

关于讲座的其余部分,讲师试图描述一种基于堆栈的计算算术表达式的机器。机器通过从堆栈顶部连续弹出 3 个元素来运行。前两个元素是操作数,第三个元素是运算符(+、-、*、/)。然后它将这个运算符应用于操作数,并将结果压入堆栈。该过程继续进行,直到堆栈上只有一个元素,即表达式的值。

因此,假设我们首先将值“+/*23-21*5-41”按从左到右的顺序压入堆栈。然后我们从顶部弹出 3 个元素。后进先出,即前 3 个元素依次为“1”、“4”和“-”。我们将数字 3(4-1 的结果)压入堆栈,然后弹出三个最顶层元素:3、5、*。将结果 15 压入堆栈,依此类推。

于 2010-09-29T20:13:02.173 回答
3

堆栈原则上非常简单:想象一把步枪的弹夹 - 你只能访问最上面的子弹 - 取出它称为“pop”,插入一个新子弹称为“push”。
一个非常有用的示例是允许您“撤消”的应用程序。
想象一下,您将应用程序的每个状态都保存在堆栈中。例如,在用户进行每种类型之后应用程序的状态。
现在,当用户按下“撤消”时,您只需从堆栈中“弹出”前一个状态。对于用户执行的每个操作 - 您将新状态“推送”到堆栈(这当然是简化的)。
关于您的讲师具体在做什么-为了解释它,更多信息会有所帮助..

于 2010-09-29T19:35:38.673 回答
3
  • push = 添加到堆栈
  • pop = 从堆栈中移除
于 2015-10-12T01:41:46.313 回答
2

简单地:

  • pop:返回顶部的项目,然后将其从堆栈中删除

  • push:将一个项目添加到堆栈的顶部。

于 2018-03-20T14:15:03.457 回答
1

毕竟这些好例子亚当山克曼仍然无法理解。我认为您应该打开一些代码并尝试一下。第二次你尝试 myStack.Push(1) 和 myStack.Pop(1) 你真的应该得到图片。但从表面上看,即使这样对你来说也是一个挑战!

于 2010-09-29T20:36:18.813 回答