1.3节后习题
题目要求
1. 假设用长度为11的数组作为顺序队列,初始为空。分别绘出做完下列操作后的队列示意图。若有元素不能入队,说明理由。操作序列如下:
- A、B、C、D、E 依次入队;
- A、B 依次出队;
- F、G、H、I、J 依次入队;
- O、P、Q、R 依次入队。
2. 利用两个顺序栈 S1 和 S2 模拟一个队列。实现入队和出队操作,并说明基本思路。
操作序列/关键信息:
- 循环队列的 front、rear 变化及存储示意;
- 两栈入队直接压入 S1,出队时 S2 不空则弹出,否则将 S1 内容逆序压入 S2。
参考答案与解析
参考答案 - 顺序循环队列操作示意图
一、顺序循环队列操作示意图
操作 | front | rear | 队列内容 |
---|---|---|---|
初始 | 0 | 0 | [-, -, -, -, -, -, -, -, -, -, -] |
入队 A,B,C,D,E | 0 | 5 | [A, B, C, D, E, -, -, -, -, -, -] |
出队 A,B | 2 | 5 | [A, B, C, D, E, -, -, -, -, -, -] (实际存储 C,D,E 在索引2-4) |
入队 F,G,H,I,J | 2 | 10 | [A, B, C, D, E, F, G, H, I, J, -] |
入队 O,P | 2 | 1 | [O, P, C, D, E, F, G, H, I, J, -] (Q,R 无法入队,队满) |
注:循环队列满条件为 (rear + 1) % 11 == front。最多存储 10 个元素。
参考答案 - 两栈模拟队列
二、两栈模拟队列
基本思路:
- 入队(enqueue):直接将元素压入 S1。
- 出队(dequeue):若 S2 非空,直接弹出 S2 顶;否则将 S1 所有元素依次弹出并压入 S2,再弹出 S2 顶。
cpp
#include <iostream>
#include <stack>
#include <stdexcept>
class QueueUsingStacks {
private:
std::stack<int> S1;
std::stack<int> S2;
public:
void enqueue(int x) {
S1.push(x);
}
int dequeue() {
if (!S2.empty()) {
int v = S2.top(); S2.pop(); return v;
} else if (!S1.empty()) {
while (!S1.empty()) {
S2.push(S1.top()); S1.pop();
}
int v = S2.top(); S2.pop(); return v;
} else {
throw std::runtime_error("Queue is empty");
}
}
};
核心知识点
循环队列
- 队空条件:front == rear。
- 队满条件:(rear + 1) % maxsize == front。
两栈模拟队列
- 栈的后进先出(LIFO)特性。
- 入队效率:O(1);出队效率:均摊 O(1)(摊销分析)。