Зачем использовать два стека для создания очереди?

Я вижу преимущество использования двух стеков, если используется реализация массива, поскольку стеки легче реализуются с использованием массивов, чем очереди. Но если используются связанные списки, в чем преимущество? Акт добавления стека в очередь увеличивает накладные расходы как для реализаций связанного списка, так и для реализаций массива.

4 ответов


Это обычный способ реализации очереди в функциональных языках программирования с чисто функциональными (неизменяемыми, но разделяющими структуру) списками (например, Clojure, Haskell, Erlang...):

  • используйте пару списков для представления очереди, где элементы находятся в порядке FIFO в первом списке и в порядке LIFO во втором списке
  • enqueue к очереди, добавив ко второму списку
  • извлечения из очереди, взяв первый элемент первого список
  • если первый список пуст: переверните второй список и замените им первый список и замените второй список пустым списком

(все операции возвращают новый объект очереди в дополнение к любым возможным возвращаемым значениям)

дело в том, что добавление (удаление) элемента в (из) передней части чисто функционального списка равно O (1), а обратная операция, которая равна O(n), амортизируется по всем dequeues, поэтому она близка к O(1), таким образом предоставление вам реализации очереди ~O(1) с неизменяемыми структурами данных.


этот подход может быть использован для создания lock-free очередь с использованием двух атомарных односвязанных стеков на основе списка, таких как Win32: Взаимосвязанные Односвязные Списки. Алгоритм может быть описан в ответ liwp, хотя шаг переупаковки (пуля 4) можно немного оптимизировать.

структуры и алгоритмы данных без блокировки - очень интересная (для некоторых из нас) область программирования, но их нужно использовать очень осторожно. В общая ситуация, алгоритмы на основе блокировки более эффективны.


вы можете создать неизменяемую очередь, используя два неизменяемых стека.

но, если вы просто хотите изменяемую очередь, использование двух стеков-отличный способ сделать ее медленнее и сложнее, чем просто использовать связанный список.


Это хороший опыт, но не практическую.