如何实现两个堆栈的队列

时间:2015-12-04 23:36:49

标签: data-structures stack queue

今天我进行了数据结构考试。其中一个问题是如何实现队列函数,这些函数在给定堆栈s1s2的情况下排队并出列。我用过这种方法,这是对的吗?

enqueue(& item)
   if(!s2.isEmpty())
      s1.push(s2.pop());
   s1.push(item);
dequeue
   if(!s1.isEmpty())
      s2.push(s1.pop());
   return s2.pop();

2 个答案:

答案 0 :(得分:1)

通常,如果您有这样的堆栈:

[1,2,3,4]

这里的问题是popping会想要以LIFO顺序弹出,这意味着它会想要弹出元素4。队列应按FIFO顺序弹出,并弹出元素1

为了获得这种行为,我们基本上需要能够以相反的顺序弹出。第二个堆栈可以允许我们实际反转堆栈的内容。想象一下,在上面的堆栈中循环并从中弹出并将内容推送到另一个堆栈:

[1,2,3,4] []
[1,2,3]   [4]
[1,2]     [4,3]
[1]       [4,3,2]
[]        [4,3,2,1]

现在当我们从第二个堆栈弹出时,我们会根据需要弹出1。

但要以正确的顺序执行此操作,我们必须首先遍历所有第一个堆栈的元素并将它们传输到第二个堆栈。所以在你的入队/出队操作中实际上应该有一些循环来翻转(反向)这些堆栈的内容。

第二个堆栈就派上用场了:它允许你通过传输来反转堆栈的内容。但是你需要一个循环,因为想象一下排队4个元素。现在要出列,你需要一个循环来反转内容。您可以将s1视为推送堆栈,将s2视为弹出堆栈。看起来你有正确的想法,但我们需要稍微调整一下:

enqueue(item):
   while(!s2.isEmpty())
      s1.push(s2.pop());
   s1.push(item);

dequeue(item):
   while(!s1.isEmpty())
      s2.push(s1.pop());
   return s2.pop();

答案 1 :(得分:1)

对于它的价值,入队不需要循环。如果你有两个堆栈,enqueueStack和dequeueStack,你只需要将它推入enqueueStack并反转到dequeueStack,只要它是空的。

enqueue(item):
    enqueueStack.push(item);
dequeue(item):
    if(dequeueStack.isEmpty()){
        while(!enqueueStack.isEmpty()){
            dequeueStack.push(enqueueStack.pop());
        }
    }
    return dequeueStack.pop()

如果堆栈变大,可节省一点时间。