- 了解栈与队列的内部实现机制
- C++中stack 是容器么?
- 我们使用的stack是属于哪个版本的STL?
- 我们使用的STL中stack是如何实现的?
- stack 提供迭代器来遍历stack空间么?
- 容器适配器(C++ Primer 9.6 P329)
题目描述:仅使用两个栈实现先入先出队列。
队列应当支持一般队列支持的所有操作(push、pop、peek、empty)
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
说明:只有 push to top, peek/pop from top, size, 和 is empty 操作是合法的。
视频讲解https://www.bilibili.com/video/BV1nY4y1w7VC文章讲解https://programmercarl.com/0232.%E7%94%A8%E6%A0%88%E5%AE%9E%E7%8E%B0%E9%98%9F%E5%88%97.html
1 2 3 4
4 1 2 3
3 4 1 2
2 3 4 1
1 2 3 4
1 2
2 1
1 2
1 2 3 4
- 思路:
- 左栈为空,右栈元素依次转移到左栈(LIFO→FILO)
- 左栈不为空,则左栈顶元素为队列开头(FILO→LIFO)
- 右→左发生在左栈为空的时候,且右栈元素全部转移出来,说明当前右栈元素进栈之前,已经进行了右→左的操作,则一定有左栈元素先于右栈
- 代码:
class MyQueue {
public:
stack<int> LeftStack;
stack<int> RightStack;
// 初始化
MyQueue() {
}
// 压入右栈
void push(int x) {
RightStack.push(x);
}
// 如果左栈不为空,直接弹出左栈顶
// 如果左栈为空,先将右栈中的所有元素转移到左栈,再弹出左栈顶
int pop() {
if (LeftStack.empty()) {
while (!RightStack.empty()) {
int value = RightStack.top();
RightStack.pop();
LeftStack.push(value);
}
}
int result = LeftStack.top();
LeftStack.pop();
return result;
}
// 即返回左栈顶元素
// 或右栈底
int peek() {
if (LeftStack.empty()) {
while (!RightStack.empty()) {
int value = RightStack.top();
RightStack.pop();
LeftStack.push(value);
}
}
return LeftStack.top();
}
// 左栈和右栈都为空才算空
bool empty() {
if (LeftStack.empty() && RightStack.empty()) {
return true;
}
return false;
}
};
⭐函数复用
// 代码随想录
class MyQueue {
public:
stack<int> stIn;
stack<int> stOut;
/** Initialize your data structure here. */
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
stIn.push(x);
}
/** Removes the element from in front of queue and returns that element. */
int pop() {
// 只有当stOut为空的时候,再从stIn里导入数据(导入stIn全部数据)
if (stOut.empty()) {
// 从stIn导入数据直到stIn为空
while(!stIn.empty()) {
stOut.push(stIn.top());
stIn.pop();
}
}
int result = stOut.top();
stOut.pop();
return result;
}
/** Get the front element. */
int peek() {
int res = this->pop(); // 直接使用已有的pop函数
stOut.push(res); // 因为pop函数弹出了元素res,所以再添加回去
return res;
}
/** Returns whether the queue is empty. */
bool empty() {
return stIn.empty() && stOut.empty();
}
};
pop() 比 peek() 多了一步,复用 peek() 更方便:
// 复用peek()
class MyQueue {
public:
stack<int> LeftStack;
stack<int> RightStack;
// 初始化
MyQueue() {
}
// 压入右栈
void push(int x) {
RightStack.push(x);
}
// 复用peek()
// 弹出左栈顶元素
int pop() {
int result = this->peek();
LeftStack.pop();
return result;
}
// 若左栈为空,先将右栈元素全部转移到左栈
// 获取左栈顶元素
int peek() {
if (LeftStack.empty()) {
while (!RightStack.empty()) {
LeftStack.push(RightStack.top());
RightStack.pop();
}
}
return LeftStack.top();
}
// 左栈、右栈均为空,队列才为空
bool empty() {
return LeftStack.empty() && RightStack.empty();
}
};
题目描述:仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
视频讲解https://www.bilibili.com/video/BV1Fd4y1K7sm/?spm_id_from=333.788&vd_source=f98f2942b3c4cafea8907a325fc56a48文章讲解https://programmercarl.com/0225.%E7%94%A8%E9%98%9F%E5%88%97%E5%AE%9E%E7%8E%B0%E6%A0%88.html
- 思路:
- 两个队列实现栈:que1,que2(弹出队尾元素时,用于对前面元素进行备份)
- push(): 直接插入到que1队尾
- pop(): 把前 size - 1 个元素依次挪入que2,弹出队首元素,其余元素归位
- top(): 直接获取que1队尾元素
- empty():直接判断que1是否为空
- 一个队列实现栈:que
- push(): 直接插入到que队尾
- pop(): 把前 size - 1 个元素依次挪到队尾,弹出队首元素
- top(): 直接获取que队尾元素
- empty():直接判断que是否为空
- 两个队列实现栈:que1,que2(弹出队尾元素时,用于对前面元素进行备份)
- 代码:
// 两个队列实现栈:
class MyStack {
public:
queue<int> que1;
queue<int> que2; // 辅助队列,用来备份
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
que1.push(x);
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int size = que1.size();
size--;
while (size--) { // 将que1 导入que2,但要留下最后一个元素
que2.push(que1.front());
que1.pop();
}
int result = que1.front(); // 留下的最后一个元素就是要返回的值
que1.pop();
que1 = que2; // 再将que2赋值给que1
while (!que2.empty()) { // 清空que2
que2.pop();
}
return result;
}
/** Get the top element. */
int top() {
return que1.back();
}
/** Returns whether the stack is empty. */
bool empty() {
return que1.empty();
}
};
// 一个队列实现栈:
class MyStack {
public:
queue<int> que;
/** Initialize your data structure here. */
MyStack() {
}
/** Push element x onto stack. */
void push(int x) {
que.push(x);
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int size = que.size();
size--;
while (size--) { // 将队列头部的元素(除了最后一个元素外) 重新添加到队列尾部
que.push(que.front());
que.pop();
}
int result = que.front(); // 此时弹出的元素顺序就是栈的顺序了
que.pop();
return result;
}
/** Get the top element. */
int top() {
return que.back();
}
/** Returns whether the stack is empty. */
bool empty() {
return que.empty();
}
};