为什么要使用两个堆栈来建立队列?

时间:2010-01-12 15:39:27

标签: list abstract-data-type

如果使用数组实现,我可以看到使用两个堆栈的优势,因为使用数组比使用数组更容易实现堆栈。 但是如果使用链接列表,有什么优势呢? 将堆栈弹出到队列中的行为增加了链表和数组实现的开销。

4 个答案:

答案 0 :(得分:18)

这是在函数式编程语言中使用纯函数(不可变但共享结构)列表实现队列的常用方法(例如Clojure,Haskell,Erlang ......):

  • 使用一对列表来表示队列,其中元素在第一个列表中按FIFO顺序排列,在第二个列表中以LIFO顺序排列
  • 通过添加到第二个列表
  • 排队到队列
  • 通过获取第一个列表的第一个元素
  • 从队列中出队
  • 如果第一个列表为空:反转第二个列表并用它替换第一个列表,并用空列表替换第二个列表

(除了任何可能的返回值之外,所有操作都返回新的队列对象)

关键是在纯函数列表的前面添加(删除)元素是O(1),而O(n)的反向操作在所有的二次队列中分摊,所以它接近于O(1),从而为您提供具有不可变数据结构的~O(1)队列实现。

答案 1 :(得分:5)

此方法可用于使用两个基于原子单链接列表的堆栈构建lock-free队列,例如由Win32提供:Interlocked Singly Linked Lists。 该算法可以如liwp's answer中所述,尽管可以稍微优化重新包装步骤(项目符号4)。

无锁数据结构和算法是一个非常令人兴奋的(对我们中的一些人)编程领域,但必须非常小心地使用它们。在一般情况下,基于锁的算法更有效。

答案 2 :(得分:3)

您可以使用两个不可变堆栈创建不可变队列。

但是,如果你只想要一个可变队列,那么使用两个堆栈是一种很好的方法,可以使它比使用链表更慢,更复杂。

答案 3 :(得分:-2)

这是一个很好的学习经历,但不是一个实用的经历。