← Все вопросы

Что такое очередь (queue) и как работают enqueue/dequeue?

Задан 3 дня назад288 просмотров2 ответа
5

Читаю про очереди и немного путаюсь. Понял, что это FIFO — кто первый пришёл, тот первый ушёл, как в магазине. Но как это реализовать в Python нормально? Видел, что используют обычный список, но кто-то говорил, что это плохо. Можете объяснить на пальцах, что такое enqueue и dequeue и где очереди реально применяют?

2 ответа

5
✓ Принятый ответ — помог автору

Хороший вопрос, давай по порядку.

Очередь (queue) — это структура данных, которая работает по принципу FIFO (First In, First Out): первый добавленный элемент будет первым извлечён. Аналогия с очередью в магазине у тебя абсолютно верная.

Две базовые операции:

  • enqueue — добавить элемент в хвост очереди.
  • dequeue — извлечь элемент из головы очереди.

Теперь про реализацию. Списком list пользоваться можно, но pop(0) для извлечения из начала работает за O(n) — Python физически сдвигает все оставшиеся элементы влево. На больших объёмах это убивает производительность.

Правильный инструмент — collections.deque. У него извлечение из обоих концов за O(1):

from collections import deque

queue = deque()

# enqueue — добавляем в хвост
queue.append("Аня")
queue.append("Боря")
queue.append("Вика")

# dequeue — забираем из головы
first = queue.popleft()   # 'Аня'
print(first, list(queue)) # Аня ['Боря', 'Вика']

Почему deque быстрее? Внутри это двусвязный блок-список, а не один непрерывный массив, поэтому добавление/удаление с краёв не требует сдвига.

Где применяют очереди:

  • BFS (обход графа в ширину) — соседей кладём в очередь и обрабатываем по порядку.
  • Буферы и task-очереди (обработка задач в порядке поступления).
  • Очереди печати, обработка событий.

Итог: для очереди всегда бери deque, а list.pop(0) оставь в прошлом.

4

Добавлю практическую деталь: если тебе нужна потокобезопасная очередь (несколько потоков пишут/читают), то бери не deque, а queue.Queue из стандартной библиотеки — там уже встроены блокировки.

from queue import Queue
q = Queue()
q.put(1)      # enqueue
x = q.get()   # dequeue

Но для однопоточного кода и алгоритмов (тот же BFS) collections.deque быстрее и проще — лишние локи не нужны.

Ваш ответ

Войдите, чтобы ответить на вопрос.
Поддержать проект