545 KiB
栈习题
概念
例题 栈和队列具有相同的()。
$A.$抽象数据类型
$B.$逻辑结构
$C.$存储结构
$D.$运算
解:$B$。栈和队列的逻辑结构都是相同的,都属于线性结构,只是它们对数据的运算不同。
结构选择
例题 设链表不带头结点且所有操作均在表头进行,则下列最不适合作为链栈的是()。
$A.$只有表头结点指针,没有表尾指针的双向循环链表
$B.$只有表尾结点指针,没有表头指针的双向循环链表
$C.$只有表头结点指针,没有表尾指针的单向循环链表
$D.$只有表尾结点指针,没有表头指针的单向循环链表
解:$C$。对于双向循环链表,不管是表头指针还是表尾指针,都可以很方便地找到表头结点,方便在表头做插入或删除操作。而单循环链表通过尾指针的$next$指针可以很方便地找到表头结点,但通过头指针指向的就是头,对于头的操作则需要遍历一次链表到表尾。对于$C$,插入和删除结点后,找尾结点需要花费$O(n)$的时间。
出栈排列
如果有$n$个不同的元素进栈,出栈元素不同排列的个数为$\dfrac{1}{n+1}C_{2n}^n=\dfrac{1}{n+1}\dfrac{(2n)!}{n!\times n!}$,这就是卡特兰数。
例题 $3$个不同元素依次进栈,能得到()种不同的出栈序列。
A.4
B.5
C.6
D.7
解:$B$。根据公式可得$\dfrac{6\times5\times4}{4\times3\times2\times1}=5$。
栈的应用
中缀转后缀
从左到右扫描中缀表达式。遇到数字加入后缀表达式,遇到运算符:
- 若为“(”,入栈。
- 若为“)”,则依次把栈中的运算符加入后缀表达式,直到出现“(”,从栈中删除“(”。
- 若为除括号外的其他运算符,当其优先级高于除“(”外的栈顶运算符时,直接入栈。否则从栈顶开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,直到一个比它优先级低的或遇到了一个左括号为止。
当扫描的中缀表达式结束时,栈中的所有运算符依次出栈加入后缀表达式。
如中缀表达式:$9+(3-1)*3+10/2$。
由于数字都是直接输出,所以转换的重点是符号出栈入栈的条件。进入栈的符号如果优先级压不住栈内元素的优先级,则栈内元素会逐个弹出再让这个入栈符号入栈,如果优先级高则可以压住全部不让出栈。
| 扫描符 | 操作 | 栈 | 表达式 |
|---|---|---|---|
| 9 | 输出 | 9 | |
| + | 入栈 | + | 9 |
| ( | 入栈 | +( | 9 |
| 3 | 输出 | +( | 93 |
| - | 入栈 | +(- | 93 |
| 1 | 输出 | +(- | 931 |
| ) | 出栈 | + | 931- |
| * | 入栈 | +* | 931- |
| 3 | 输出 | +* | 931-3 |
| + | 出栈 | + | 931-3*+ |
| 10 | 输出 | + | 931-3*+10 |
| / | 入栈 | +/ | 931-3*+10 |
| 2 | 输出 | +/ | 931-3*+102 |
| 结尾 | 出栈 | 931-3*+102/+ |
例题 已知操作符包括+、-、*、/、(和)。将中缀表达式$a+b-a*((c+d)/e-f)+g$转换为等价的后缀表达式$ab+acd+e/f-*-g+$时用栈来存放暂时不能确定运算次序的操作符。若栈初始时为空,则转换过程中同时保存在栈中的操作符的最大个数为()。
A.5
B.7
C.8
D.11
解:$A$。$isp$是栈内优先级,$icp$是栈外优先级,添加#作为结束符。
| 操作符 | # | ( | *,/ | +,- | ) |
|---|---|---|---|---|---|
| isp | 0 | 1 | 5 | 3 | 6 |
| icp | 0 | 6 | 4 | 2 | 1 |
例题 假设栈初始为空,将中缀表达式$a/b+(cd-ef)/g$转为等价的的后缀表达式的过程中,当扫描到$f$时,栈中的元素依次是()。
A.+(*-
B.+(-*
C./+(*-*
D./+-*
解:$B$。将#作为初始值。