椰程信奥 · 教案
栈与队列 · 教案(45 分钟,对应课件 20 页)
一、教学目标
| 维度 | 具体目标 |
| 知识与技能 | ① 徒手写出数组模拟栈与队列;② 掌握循环队列判空、判满、求个数三公式;③ 熟练使用 stack / queue 接口。 |
| 过程与方法 | 通过"预测—验证"式动画操作,把指针移动内化为可推演的模型。 |
| 情感态度价值观 | 体会"限制操作换取正确性"的工程思想;养成先判空再取值的防御性编码习惯。 |
二、重点难点
重点
栈 / 队列的指针模型;循环队列三件套;两道真题的建模。
难点
循环队列牺牲一格的必要性;(tail-head+M)%M 中 +M 的原因;"围成一圈"翻译为队列。
三、教学过程
| 环节 | 教师活动 | 学生活动 | 设计意图 |
| ① 引入(4′) | 「一摞盘子,你能从中间抽一个吗?排队买票,你能插队吗?」课件第 3 页。 |
说出两条"规矩":只能从上拿 / 只能排后面 | 生活经验锚定抽象规则 |
| ② 栈·手写(10′) | 第 4–5 页:先问后点——「现在 top=2,push 之后 top 是几?值放在哪一格?」 |
先口头回答,再看动画验证 | 把指针移动变成可验证预测 |
| ③ STL 坑(4′) | 「int x = st.pop(); 会怎样?」——编译报错,因为 pop 返回 void。 |
改成 x=st.top(); st.pop(); | 提前拆除高频错误 |
| ④ 假溢出(8′) | 第 8 页:让学生连续"入一个、出一个",直到 tail 顶到末尾。追问:「数组真的满了吗?」 |
指出划掉的格子,说出"前面空着" | 制造认知冲突,引出循环队列 |
| ⑤ 循环队列(10′) | 第 9 页环形动画连续入到队满,追问:「M=8,现在存了几个?」 |
回答 7 个,说明第 8 格去哪了 | 本讲难点的可视化突破 |
| ⑥ 对比选型(4′) | 第 12 页:1、2、3、4 依次放入,再依次取出。 | 预测两种结构的取出顺序 | 一句话记住选型 |
| ⑦ 例题与检测(5′) | 第 13–16 页真题动画;第 17 页三道检测。 | 完成检测并订正 | 当堂形成性评价 |
四、易错点清单
| # | 易错说法 / 写法 | 判断 | 正确做法 |
| 1 | int x = st.pop(); | ✗ | pop() 返回 void,必须 x=st.top(); st.pop(); |
| 2 | 不判空就 top() / front() | ✗ | 未定义行为,先 if(!empty()) |
| 3 | 个数写成 (tail-head)%M | ✗ | C++ 负数取模仍为负,必须 (tail-head+M)%M |
| 4 | 循环队列能存 M 个元素 | ✗ | 只能存 M−1 个,留一格区分空与满 |
| 5 | 括号匹配只统计左右括号数量 | ✗ | )( 数量相等但顺序错,必须用栈 |
| 6 | 猴子淘汰后忘记 k=1 | ✗ | 淘汰分支必须重置报数计数器 |
五、板书
栈:一个口 top=−1 push: stk[++top]=x pop: top-- FILO
队列:两个口 head / tail FIFO → 循环:(i+1)%M
循环:空 head==tail 满 (tail+1)%M==head 个数 (tail-head+M)%M ★+M
选型:最近 / 嵌套 / 撤销 → 栈;依次 / 轮转 / 排队 → 队列
六、作业
- 完成 Hydro 当堂测评两题:BRACKET(表达式括号匹配)、MONKEY(猴子选大王)。
- 拓展题(选做):后缀表达式求值、Blah 数集(课件第 16 页给了方向)。
- 思考题:循环队列如果不想牺牲格子,还能怎么判满?(提示:额外用一个
cnt 变量。)