c ++ deque проти черги проти стека


82

Черга та стек - це структури, про які широко згадують. Однак у C ++ для черги це можна зробити двома способами:

#include <queue>
#include <deque>

але для стека ви можете зробити це лише так

#include <stack>

Моє запитання полягає в тому, яка різниця між чергою та деке, чому запропоновано дві структури? Для стека може бути включена будь-яка інша структура?

Відповіді:


77

Морон / Арьябхатта правильний, але трохи більше деталей може бути корисним.

Черга та стек - це контейнери вищого рівня, ніж deque, vector або list. Під цим я маю на увазі, що ви можете створити чергу або скласти контейнери нижчого рівня.

Наприклад:

  std::stack<int, std::deque<int> > s;
  std::queue<double, std::list<double> > q;

Побудує стек ints, використовуючи deque як базовий контейнер, і чергу вдвічі, використовуючи список як базовий контейнер.

Ви можете сприймати це sяк заборонену дію та qяк обмежений список.

Все, що потрібно, це те, що контейнер нижчого рівня реалізує методи, необхідні контейнеру більш високого рівня. Це back(), push_back()і pop_back()для стека і front(), back(), push_back(), і pop_front()для черги.

Докладніше див. Стек і черга .

Що стосується декеля, це набагато більше, ніж черга, куди ви можете вставити обидва кінці. Зокрема, він має довільний доступ operator[]. Це робить його більше схожим на вектор, але вектор, куди ви можете вставити та видалити на початку за допомогою push_front()і pop_front().

Детальніше див. У deque .


16
stackі queue просто обмежити deque повний набір функцій.
bobobobo

59

Queue: ви можете вставити лише в один кінець, а вийняти з іншого.

Deque: ви можете вставити та вийняти з обох кінців.

Отже, використовуючи a Deque, ви можете змоделювати Queueяк a, так і a Stack.

Підказка:
Dequeскорочення від " D uble e nded que ue".


4
чи не буде надмірним, якщо ви використовуєте Deque для моделювання стека?
skydoor

Ви не можете змоделювати стек за допомогою черги.
R Samuel Klatchko

1
Різниць набагато більше. queueне відповідає вимогам контейнера. У нього немає ітераторів, заради бога!
Potatoswatter

@skydoor З усіх стандартних бібліотечних контейнерів, деке, мабуть, є тим, що має найнижчі накладні витрати.

3
@skydoor: Так само, як FYI, STL за замовчуванням std::stackвикористовує std::dequeяк резервний контейнер. Я спекулюю на цій причині тут: stackoverflow.com/questions/102459/… (в основному, що зростання А - dequeце низькі накладні витрати).
Michael Burr

33

dequeє шаблоном контейнера. Він задовольняє вимогам до послідовності з ітераторами довільного доступу, подібно до a vector.

queueце не контейнер, це адаптер . Він містить контейнер і забезпечує інший, більш конкретний інтерфейс. Використовуйте, queueколи ви хочете запам'ятати (або нагадати), щоб уникнути операцій, крім push[_back]і pop[_front], frontі back, sizeі empty. Ви взагалі не можете розглядати елементи всередині queueкрім першого та останнього!


7
Адаптер - іншими словами непотрібна функціональність каліка , але адаптер цілком чудовий
bobobobo

22

У бібліотеці C ++ обидва std::stackта std::queueреалізовані як контейнерні адаптери . Це означає, що вони забезпечують інтерфейс стека або черги відповідно, але жоден із них насправді не є контейнером. Натомість вони використовують якийсь інший контейнер (наприклад, std::dequeабо std::listнасправді зберігають дані), а std::stackклас просто має крихітний біт коду для перекладу pushта popдо push_backта pop_backstd::queueробить приблизно те саме, але використовуючи push_backта pop_front).


Для queue, VS також , здається, на карті , popщоб pop_frontі pushдо push_back, так що я думаю , це залежить від конкретної реалізації.
chappjc

@chappjc: Ні - повторна перевірка, просто пам’ять у мене вимкнено. pop_frontі push_backє тим, що потрібно. Мої вибачення.
Джеррі Коффін,

7

Deque - це двостороння черга, яка дозволяє легко вставляти / виймати з будь-якого кінця. Черги дозволяють вставляти лише в один кінець, а отримувати з іншого.


5

deque підтримує вставку / попку ззаду та спереду

Черга підтримує лише вставку ззаду та висунення спереду. Ви знаєте, FIFO (перший у першому виході).



0

Зміна черги пріоритетів відбувається згідно з деяким порівнянням порядку (пріоритету), а не порядком черги.

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

Черги пріоритетів часто реалізуються за допомогою купи.

Майк Андерсон тут:
https://www.quora.com/What-is-the-difference-between-a-priority-queue-and-a-queue


0

In deque (подвійна черга) Елемент можна вставити ззаду і видалити форму назад (Те саме, що стек), але в черзі видалити лише спереду.


Ця відповідь не додає нічого нового до теми (а більшість відповідей
дано
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.