Day10 栈与队列
一、栈与队列
1、栈
概念
栈是一种线性数据结构,具有**先进后出(LIFO)**的特性。
基本操作
- push:将一个元素压入栈顶,即在栈顶添加一个元素。
- pop:将栈顶元素弹出,即移除栈顶元素,并返回该元素。
- top/peek:返回栈顶元素,但不弹出。
- is_empty:判断栈是否为空,如果为空则返回true,否则返回false。
- is_full:判断栈是否已满,如果已满则返回true,否则返回false。在使用静态数组实现栈时需要考虑。
- size:返回栈中元素的个数。
2、队列
概念
队列是一种线性数据结构,具有**先进先出(FIFO)**的特性。
基本操作
- enqueue:在队列尾部插入一个元素,即向队列中添加一个元素。
- dequeue:从队列头部删除一个元素,即删除队列中的第一个元素,并返回该元素。
- is_empty:判断队列是否为空,如果为空则返回true,否则返回false。
- is_full:判断队列是否已满,如果已满则返回true,否则返回false。在使用静态数组实现队列时需要考虑。
- size:返回队列中元素的个数。
- clear:清空队列
- front:返回队列中的第一个元素,如果队列为空,则返回’undefined’
- back:返回队列中的尾部第一个元素
二、力扣相关例题
232. 用栈实现队列
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(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 操作
示例 :
输入:
[“MyQueue”, “push”, “push”, “peek”, “pop”, “empty”]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]
解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false
解题关键:
①如何用两个栈模拟队列:定义两个栈,首先将元素全放进去第一个栈中,紧接着将第一个栈中的元素放进第二个栈中,这样出栈的元素顺序就跟队列一样
②明白栈的基本操作
class MyQueue {
public:
//定义两个栈,stackIn和stackOut
stack<int> stackIn;
stack<int> stackOut;
//这里是初始化数据结构
MyQueue() {
}
//将元素x推到队列的后面
void push(int x) {
stackIn.push(x);
}
//从队列前面移除元素并返回该元素
int pop() {
//如果stackOut为空,将stackIn的元素都放进stackOut中
if (stackOut.empty()) {
while (! stackIn.empty()) {
stackOut.push(stackIn.top());
stackIn.pop();
}
}
int result = stackOut.top();
stackOut.pop();
return result;
}
//获取前面元素
int peek() {
//直接使用已有的pop函数,因为在同一个类中,所以可以使用this,记住是箭头
int result = this->pop();
//因为只获取元素值,所以要将元素重新入栈
stackOut.push(result);
return result;
}
//判断队列是否为空
bool empty() {
return stackIn.empty() && stackOut.empty();
}
};
225. 用队列实现栈
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
注意:
你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
示例:
输入:
[“MyStack”, “push”, “push”, “top”, “pop”, “empty”]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]
解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False
解题关键:
一个队列:
①将所要的元素值前面的元素出队列后入队列,此时就获得想要的元素
②明白队列的基本操作
两个队列:
①将所要的元素值前面的元素出que1队列后入que2队列,此时就获得想要的元素,接着将que2队列的元素装入que1队列
②明白队列的基本操作
一个队列:
class MyStack {
public:
queue<int> que;
//这里是初始化数据结构
MyStack() {
}
//将元素x入栈
void push(int x) {
que.push(x);
}
//将元素出栈
int pop() {
int len = que.size() - 1;
//将队列前面的元素出栈再重新入栈,留下最后一个元素
while (len--) {
//front()返回队列头部元素,但不删除该元素,不影响队列的状态
que.push(que.front());
que.pop();
}
int result = que.front();
que.pop();
return result;
}
//获取堆栈头元素
int top() {
//获取队列头元素值
//back()返回队列尾部的元素,但不删除该元素,不影响队列的状态
int result = que.back();
return result;
}
bool empty() {
return que.empty();
}
};
两个队列:
class MyStack {
public:
queue<int> que1;
queue<int> que2;
//这里是初始化数据结构
MyStack() {
}
//将元素x入栈
void push(int x) {
que1.push(x);
}
//将元素出栈
int pop() {
int len = que1.size() - 1;
//将队列前面的元素出栈再重新入栈,留下最后一个元素
while (len--) {
que2.push(que1.front());
que1.pop();
}
int result = que1.front();
que1.pop();
//将que2清空
//将que2赋值给que1
que1 = que2;
while (! que2.empty()) {
que2.pop();
}
return result;
}
//获取堆栈头元素
int top() {
//获取队列头元素值
int result = que1.back();
return result;
}
bool empty() {
return que1.empty() && que2.empty();
}
};
栈与队列,我来了!Fighting!