
思路 ①
一个最憨厚的思路就是,两个栈一个作为数据栈,一个作为临时栈,使用数据栈来存储队列数据。
入队列和入栈行为完全相同。
出队列时,使用另一个栈临时将栈内数据倒序,返回栈顶数据后。 将数据存回数据栈,以便不影响后续的入队列数据。


定义一个栈结构
class Stack:
def __init__(self):
self.data = []
def push(self, v):
self.data.append(v)
def pop(self):
return self.data.pop()
def is_empty(self):
return self.data == []
队列代码实现
class Queue:
def __init__(self):
self.stack1 = Stack()
self.stack2 = Stack()
def push(self, v):
self.stack1.push(v)
def pop(self):
# 将数据栈中数据倒入临时栈
while not self.stack1.is_empty():
self.stack2.push(self.stack1.pop())
# 弹出栈顶数据
top = self.stack2.pop()
# 将临时栈中数据倒入数据栈
while not self.stack2.is_empty():
self.stack1.push(self.stack2.pop())
return top
问题:
连续多次pop数据时,需要反复将数据栈数据导入临时栈,浪费资源。
改进:
两个栈一个作为入口栈处理入队列, 一个命名为出口栈处理出队列。
数据出队列时,将入口栈中的数据导入出口栈,然后将顶部数据出栈。
数据入队列时,将出口栈中可能存在的数据压回入口栈,然后将新数据入栈

由于没有将数据导回入口栈,对于后续的出队列操作,可以直接在出口栈继续进行。如队列要弹出数据2,直接再出口栈pop即可。

入队列时,要将之前可能存在于出口栈的数据导回,然后将数据放到队列末尾,如果有连续的入栈操作,只需导回一次即可。
代码实现:
class Queue:
def __init__(self):
self.stack_in = Stack()
self.stack_out = Stack()
def push(self, v):
# 出口栈中如果有数据,将其倒入入口栈
while not self.stack_out.is_empty():
self.stack_in.push(self.stack_out.pop())
# 新数据入栈
self.stack_in.push(v)
def pop(self):
# 入口栈中如果有数据,将其导入出口栈
while not self.stack_in.is_empty():
self.stack_out.push(self.stack_in.pop())
return self.stack_out.pop()
思路②
改进的思路,将连续的入队列或者出队列操作不再进行两个栈的数据转换。但入队列时还是要关注出口栈中的数据。下面再次进行改进
两个栈依然一个作为入口栈处理入队列, 一个命名为出口栈处理出队列。
数据入队列时,和入栈行为相同,直接将数据压入入口栈。
数据出队列时,检查出口栈中是否有数据,如果有数据,则直接将顶部数据返回。如果没有数据,尝试将入口栈中的数据导入出口栈,然后将顶部数据返回。
为了更加直观的展示,下面图中将栈横着放。
① 数据入队列,将数据 1 2 3 依次放入入口栈

② 数据出队列, 发现出口栈中没有数据,将入口栈中的数据 [1, 2, 3] 依次压入出口栈,出口栈中数据为 [3, 2, 1], 执行出队列,将出口栈顶部的 1 返回。
③ 后续的入队列和出队列操作,和前面步骤相同。新的数据入队列则直接压入入口栈。新的出队列请求直接从出口栈返回数据,直到出口栈为空,则再次将入口栈中的数据导入到出口栈
代码如下:
class Queue:
def __init__(self):
self.stack_in = Stack()
self.stack_out = Stack()
def push(self, v):
self.stack_in.push(v)
def pop(self):
if self.stack_out.is_empty():
while not self.stack_in.is_empty():
self.stack_out.push(self.stack_in.pop())
return self.stack_out.pop()
本文介绍了一种利用两个栈实现队列数据结构的方法,并通过逐步优化改进,减少资源浪费,提高效率。首先采用两个栈轮流倒换的方式实现队列的基本功能,随后优化入队和出队操作流程。
341

被折叠的 条评论
为什么被折叠?



