使用两个堆栈 Python 实现一个队列
Posted
技术标签:
【中文标题】使用两个堆栈 Python 实现一个队列【英文标题】:Implement A Queue using Two Stacks Python 【发布时间】:2014-04-21 06:25:03 【问题描述】:我一直在研究许多编码面试问题中的一些问题。我想知道你将如何在 Python 中使用两个堆栈来实现一个队列? Python 不是我最擅长的语言,所以我需要我能得到的所有帮助。
像入队、出队和前端函数。
【问题讨论】:
区别在于栈是FILO,队列是FIFO。如果你反转一个堆栈,你会得到想要的行为,所以你想把你的东西放在第一个堆栈中,然后通过将它们移动到第二个堆栈来反转它们。 (对吧?,我并没有真正考虑到这一点) interactivepython.org/courselib/static/pythonds/index.html 另外,this How to implement a queue using two stacks?的可能重复 【参考方案1】:class Queue(object):
def __init__(self):
self.instack=[]
self.outstack=[]
def enqueue(self,element):
self.instack.append(element)
def dequeue(self):
if not self.outstack:
while self.instack:
self.outstack.append(self.instack.pop())
return self.outstack.pop()
q=Queue()
for i in range(10):
q.enqueue(i)
for i in xrange(10):
print q.dequeue(),
【讨论】:
【参考方案2】:class MyQueue(object):
def __init__(self):
self.first = []
self.second = []
def peek(self):
if not self.second:
while self.first:
self.second.append(self.first.pop());
return self.second[len(self.second)-1];
def pop(self):
if not self.second:
while self.first:
self.second.append(self.first.pop());
return self.second.pop();
def put(self, value):
self.first.append(value);
queue = MyQueue()
t = int(raw_input())
for line in xrange(t):
values = map(int, raw_input().split())
if values[0] == 1:
queue.put(values[1])
elif values[0] == 2:
queue.pop()
else:
print queue.peek()
【讨论】:
【参考方案3】:class Stack:
def __init__(self):
self.elements = []
def push(self, item):
self.elements.append(item)
def pop(self):
return self.elements.pop()
def size(self):
return len(self.elements)
def is_empty(self):
return self.size() == 0
class CreatingQueueWithTwoStacks:
def __init__(self):
self.stack_1 = Stack()
self.stack_2 = Stack()
def enqueue(self, item):
self.stack_1.push(item)
def dequeue(self):
if not self.stack_1.is_empty():
while self.stack_1.size() > 0:
self.stack_2.push(self.stack_1.pop())
res = self.stack_2.pop()
while self.stack_2.size() > 0:
self.stack_1.push(self.stack_2.pop())
return res
if __name__ == '__main__':
q = CreatingQueueWithTwoStacks()
q.enqueue(1)
q.enqueue(2)
q.enqueue(3)
a = q.dequeue()
print(a)
b = q.dequeue()
print(b)
c = q.dequeue()
print(c)
d = q.dequeue()
print(d)
q.enqueue(5)
q.enqueue(6)
print(q.dequeue())
【讨论】:
【参考方案4】:首先,创建一个堆栈对象。然后从 2 个堆栈中创建一个队列。由于 Stack = FIFO(先进先出)和 Queue = LIFO(后进先出),将所有项目添加到“入栈”,然后将它们弹出到输出中。
class Stack:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
return self.items.pop()
def size(self):
return len(self.items)
def is_empty(self):
return self.items == []
class Queue2Stacks(object):
def __init__(self):
# Two Stacks
self.in_stack = Stack()
self.out_stack = Stack()
def enqueue(self, item):
self.in_stack.push(item)
def dequeue(self):
if self.out_stack.is_empty:
while self.in_stack.size()>0:
self.out_stack.push(self.in_stack.pop())
return self.out_stack.items.pop()
#driver code
q = Queue2Stacks()
for i in range(5):
q.enqueue(i)
for i in range(5):
print(q.dequeue(i))
给你0,1,2,3,4
【讨论】:
【参考方案5】:Stack1, Stack2.
Enqueue:
Push el into stack1.
Dequeue:
While (!empty(Stack1))
el = Pop from stack1
Push el into stack2
returnEl = Pop from Stack2
While (!empty(Stack2))
el = Pop from stack2
Push el into stack1
return returnEl
这是一种用伪代码实现算法的方法,知道基本语法用python实现应该不难。
【讨论】:
【参考方案6】:我发现这个解决方案适用于使用两个堆栈实现队列。我使用集合而不是队列。我们可以使用以下实现。对于队列上 m 个函数调用的时间成本。这种优化可以是入队和出队调用的任意组合。
#
#
class Stack():
def __init__(self):
self.stk = []
def pop(self):
"""raises IndexError if you pop when it's empty"""
return self.stk.pop()
def push(self, elt):
self.stk.append(elt)
def is_empty(self):
return len(self.stk) == 0
def peek(self):
if not self.stk.is_empty():
return self.stk[-1]
class Queue():
def __init__(self):
self.q = Stack() # the primary queue
self.b = Stack() # the reverse, opposite q (a joke: q vs b)
self.front = None
def is_empty(self):
return self.q.is_empty()
def peek(self):
if self.q.is_empty():
return None
else:
return self.front
def enqueue(self, elt):
self.front = elt
self.q.push(elt)
def dequeue(self):
"""raises IndexError if you dequeue from an empty queue"""
while not self.q.is_empty() > 0:
elt = self.q.pop()
self.b.push(elt)
val = self.b.pop()
elt = None
while not self.b.is_empty() > 0:
elt = self.b.pop()
self.q.push(elt)
self.front = elt
return val
# Now let's test
class TestQueueTwoStacks(unittest.TestCase):
def setUp(self):
self.q = Queue()
def test_queuedequue(self):
"""queue up 5 integers, check they are in there, dequeue them, check for emptiness, perform other blackbox and whitebox tests"""
self.assertTrue(self.q.is_empty())
self.assertTrue(self.q.q.is_empty())
self.assertTrue(self.q.b.is_empty())
l = range(5)
for i in l:
self.q.enqueue(i)
self.assertEqual(4, self.q.peek())
self.assertEqual(l, self.q.q.stk)
s = []
l.reverse()
for i in l:
elt = self.q.dequeue()
s.append(elt)
self.assertTrue(self.q.is_empty())
self.assertTrue(self.q.q.is_empty())
self.assertTrue(self.q.b.is_empty())
l.reverse()
self.assertEqual(s, l)
self.assertEqual([], self.q.b.stk)
self.assertEqual([], self.q.q.stk)
if __name__ == "__main__":
# unittest.main()
suite = unittest.TestLoader().loadTestsFromTestCase(TestQueueTwoStacks)
unittest.TextTestRunner(verbosity=2).run(suite)
【讨论】:
以上是关于使用两个堆栈 Python 实现一个队列的主要内容,如果未能解决你的问题,请参考以下文章