栈与队列理论基础
队列有两个口 ,队列是先进先出
栈只有一个口,所以栈是先进后出
栈先进后出 示意图如下:
232.用栈实现队列
文档讲解:代码随想录
题目
使用栈实现队列的下列操作:
push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。
要点
使用栈来模式队列的行为,如果仅仅用一个栈,是一定不行的,所以需要两个栈一个输入栈,一个输出栈,这里要注意输入栈和输出栈的关系。
在push数据的时候,只要数据放进输入栈就好;
但在pop的时候,操作就复杂一些,输出栈如果为空,就把输入栈数据全部导入进来(注意是全部导入),因为要pop的元素在输入栈的最底下
再从出栈弹出数据,如果输出栈不为空,则直接从出栈弹出数据就可以了,为什么输出栈不为空不用从输入栈导入数据呢,因为如果从输入栈导入数据到输出栈了,那么进入输出栈的数据就会覆盖原来输出栈的数据,pop的时候就会pop新导入的数据
代码实现
class MyQueue:
def __init__(self):
# 初始化两个栈,一个用于入队操作,一个用于出队操作
self.stack_in = []
self.stack_out = []
def push(self, x):
# 将元素 x 入队,直接添加到入队栈中
self.stack_in.append(x)
def pop(self):
# 出队操作
if self.empty(): # 如果队列为空,返回 None
return None
else:
if not self.stack_out: # 如果出队栈为空
# 将入队栈的元素逐个弹出并压入出队栈,实现元素顺序反转
while self.stack_in:
self.stack_out.append(self.stack_in.pop())
# 返回出队栈的栈顶元素,即队列的第一个元素
return self.stack_out.pop()
def peek(self):
# 返回队列的第一个元素,但不将其出队
value = self.pop() # 调用 pop 方法获取第一个元素
self.stack_out.append(value) # 将获取的元素重新放入出队栈中,维持队列的状态
return value # 返回获取的元素
def empty(self):
# 判断队列是否为空
return not self.stack_in and not self.stack_out # 如果入队栈和出队栈都为空,则队列为空
225. 用队列实现栈
文档讲解:代码随想录
在队列中,最后面的元素一定是最后进来的,在栈中就需要弹出这个元素,也就是要弹出的是队列中最后面的元素,所以在弹出时,把除了最后一个元素,前面的元素从队列中pop出来,再push到这个队列中即可,这样也保证了后面进来的元素在队列的末尾,相对顺序保持不变
from collections import deque # 导入 deque 模块
class MyStack:
def __init__(self):
# 初始化一个队列(使用 deque 实现)
self.que = deque()
def push(self, x):
# 将元素 x 入栈,直接添加到队列的尾部
self.que.append(x)
def pop(self):
# 出栈操作
for i in range(len(self.que) - 1):
# 将队列中除最后一个元素外的其他元素重新入队
self.push(self.que.popleft())
# 返回队列中最后一个元素,即栈顶元素
return self.que.popleft()
def top(self):
# 返回栈顶元素但不出栈
if self.empty():
return None
else:
# 获取栈顶元素
value = self.pop()
# 将栈顶元素重新入栈
self.que.append(value)
# 返回栈顶元素
return value
def empty(self):
# 判断栈是否为空
return not self.que # 如果队列为空,则栈为空