Дек. Сравнительное описание. Примеры задач: очередь с двумя открытыми концами

Модуль "Очередь и дек" • урок 5 из 7 • ~7 минут

Суть урока. Дек (deque, double ended queue) - двусторонняя очередь: вставка и удаление разрешены с обоих концов и выполняются за O(1). Дек обобщает стек и очередь: ограничив операции на одном из концов, получаем любую из этих структур. Физически: кольцевой буфер с двумя индексами или двусвязный список.
Дек. Сравнительное описание. Примеры задач: у дека включение и исключение разрешены на обоих концах, у стека работает только один конец, у очереди вход справа и выход слева
Запрет операций на одном из концов превращает дек в стек или в очередь

Определение и операции

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

Дек: последовательность из четырех ячеек, у левого конца работают PushLeft и PopLeft, у правого - PushRight и PopRight, то есть вход и выход есть с обеих сторон
Дек: оба конца открыты и на вход, и на выход

Дек как обобщение стека и очереди

Дек - функциональное объединение стека (LIFO) и очереди (FIFO):

Физическое представление

Оба знакомых способа переносятся на дек:

/* Узел двусвязного списка */
typedef struct DequeNode {
    int data;
    struct DequeNode* next; /* сосед справа */
    struct DequeNode* prev; /* сосед слева */
} DequeNode;

/* Дек: указатели на оба конца */
typedef struct Deque {
    DequeNode* left;
    DequeNode* right;
    int size;
} Deque;

Дек. Сравнительное описание. Примеры задач: где дек незаменим

Задачи "чистого дека" встречаются реже, чем задачи на стек или очередь. Классический пример - задача о птицах на проводе (Russian Code Cup 2012): птицы бегут по проводу навстречу друг другу, при столкновении разворачиваются, а добежав до края - улетают.

Ключевое наблюдение: птицы не обгоняют друг друга, поэтому их порядок на проводе не меняется, а покинуть провод может только крайняя левая или крайняя правая птица. Значит, координаты птиц достаточно хранить в деке: вылет птицы - это PopLeft или PopRight, O(1) на событие.

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

А как в Python? Дек входит в стандартную библиотеку - collections.deque: append / appendleft, pop / popleft, все за O(1). Это тот самый инструмент, который рекомендован вместо списка везде, где нужна работа с началом последовательности.

Коротко: главное

  • Дек - двусторонняя очередь: вставка, удаление и чтение с обоих концов за O(1).
  • Обобщает стек и очередь: ограничение операций на концах дает любую из них.
  • Статическое представление - кольцевой буфер с двумя индексами.
  • Динамическое - двусвязный список (next + prev, указатели left и right).
  • Область применения: выбывают только крайние элементы, порядок внутри сохраняется.

Проверьте себя

Как из дека получить стек?

Как вам урок? Спасибо за отзыв!