【问题标题】:How to Implement a Queue With Two Stacks如何实现具有两个堆栈的队列
【发布时间】:2016-03-10 00:45:31
【问题描述】:

今天我参加了数据结构考试。问题之一是如何在给定堆栈s1s2 的情况下实现入队和出队的队列函数。我用过这个方法,对吗?

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

【问题讨论】:

  • @kirk 现在您知道要对 SwiftKey 产生的任何内容进行校对三倍。

标签: data-structures stack queue


【解决方案1】:

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

[1,2,3,4]

这里的问题是弹出将要以 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();

【讨论】:

    【解决方案2】:

    不管怎样,入队不需要循环。如果你有两个栈,enqueueStack 和 dequeueStack,你只需要 push 到 enqueueStack 并在 dequeueStack 为空时反转。

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

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

    【讨论】:

      猜你喜欢
      • 2010-10-15
      • 2010-09-09
      • 2018-06-14
      • 2012-09-02
      • 1970-01-01
      • 1970-01-01
      • 2014-04-21
      • 2017-12-21
      • 2014-12-23
      相关资源
      最近更新 更多