1 问题
如何用栈实现队列。
2 方法
(1)void push(int x) 将元素 x 推到队列的末尾
(2)int pop() 从队列的开头移除并返回元素
(3)int peek() 返回队列开头的元素
(4)boolean empty() 如果队列为空,返回 true ;否则,返回 false
代码清单 1
class MyQueue: def __init__(self): """ in主要负责push,out主要负责pop """ self.stack_in = [] self.stack_out = []# python的list像栈,先入后出。需要实现队列,先入先出。# ✔ def push(self, x: int) -> None: """ 有新元素进来,就往in里面push """ self.stack_in.append(x)# ✔ def pop(self) -> int: """ Removes the element from in front of queue and returns that element. """ if self.empty(): return None # if self.stack_in: # for i in range(len(self.stack_in)): # self.stack_out.append(self.stack_in.pop()) # return self.stack_out.pop()# 以上会出错,例如:# ["MyQueue","push","push","push","push","pop","push","pop","pop","pop","pop"]# [[],[1],[2],[3],[4],[],[5],[],[],[],[]]# 输出# [null,null,null,null,null,1,null,5,2,3,4]# 预期结果# [null,null,null,null,null,1,null,2,3,4,5]# push[5]时,基于先入先出的原则,[5]应该最后被pop出来。但按照上面的错误流程,[5]会被先从in转移到out然后被pop。# 正确应该是先把out里的全pop完然后再把[5]从in转移到out然后pop。 if self.stack_out: return self.stack_out.pop() else: for i in range(len(self.stack_in)): self.stack_out.append(self.stack_in.pop()) return self.stack_out.pop()# 为什么上面有self.stack_out.pop(),下面有self.pop(),这两个有什么区别?# 区别在于,self.stack_out.pop()调用的不是我们在这里定义的pop函数。它调用的是stack_out作为list类的库函数,# 是list类固有的。每个list都有,随便新定义一个list,它也可以用.pop方法,返回的是list最末位的元素。# 例如 定义list0 = [1,2,3,4],要求return list0.pop(), list0,返回值为[4,[1,2,3]]# 下面的self.pop()是调用我们在这里定义的pop函数。 def peek(self) -> int: """ Get the front element. """ ans = self.pop() self.stack_out.append(ans) return ans def empty(self) -> bool: """ 只要in或者out有元素,说明队列不为空 """ return not (self.stack_in or self.stack_out) |
---|
3 结语
用栈实现队列,队列的各项函数操作是基于栈的函数的。在编辑队列的相关函数时,先思索其与栈的关系,如何用栈来实现,再直接调用栈的函数,就可以快速的实现队列的函数操作。
余丽媛、梁俊琦、张晓燕
2023年4月29日