Appearance
题目
下列关于栈的叙述中,错误的是( )。
I. 采用非递归方式重写递归程序时必须使用栈
II. 函数调用时,系统要用栈保存必要信息
III. 只要确定了入栈次序,即可确定出栈次序
IV. 栈是一种受限的线性表,允许在其两端进行操作
错因
A
只发现 I 错(因为见过尾递归改循环),但没有逐条审视 III 和 IV。III 是经典坑——同一入栈次序可以对应多种合法出栈次序;IV 把"两端"和"一端"混淆,乍看像在描述队列/双端队列。漏判这两条就会只选 A。
B
把唯一正确的 II 当成错的。可能是被"必须"二字带偏,想当然地把 II 也归入"绝对化叙述"。但函数调用栈是 CPU/OS 层面的标准机制(保存返回地址、参数、局部变量),从不出现例外,II 必为对。
D
把 II 误判为错(理由同 B),同时漏掉了真正错误的 I。常见心理:看到"递归→必须用栈"觉得"听起来很对",没有想到尾递归 / Fibonacci 等可以纯循环 + 几个变量改写。
总解析
逐条判定:
| 序号 | 叙述 | 判定 | 关键依据 |
|---|---|---|---|
| I | 非递归重写必须用栈 | 错 | 尾递归、Fibonacci 等可改写为纯循环 + 常数变量,不需要显式栈 |
| II | 函数调用用栈保存信息 | 对 | 调用栈保存返回地址、形参、局部变量是标准实现 |
| III | 入栈次序定 → 出栈次序定 | 错 | 入栈 1,2,3 至少可得 5 种合法出栈:123 / 132 / 213 / 231 / 321 |
| IV | 栈允许两端操作 | 错 | 栈只在栈顶一端操作;允许两端操作的是双端队列(deque) |
错误的有 I、III、IV。
最终答案是 C。
快速反例:对 III,入栈序列 1,2,3 可以得到出栈 1,3,2(1 入 1 出,2 入 3 入 3 出 2 出)和 2,1,3(1 入 2 入 2 出 1 出 3 入 3 出)等多种,可见出栈次序并不被入栈次序唯一确定。