BACK TO BLOG
Все, что нужно знать о Кольцевой очереди
Очередь (Queue) довольно простая структура данных. У неё две ключевые операции:
enqueue(): добавить в конец
dequeue(): удалить из начала
Аналогия из жизни: обычная очередь в магазине. Новый человек становится в конец, обслуживается первый.
Очередь часто реализуется на массиве (ArrayDeque в Java и collections.deque в Python), используя два указателя: front
и rear
.
Проблема: почему обычная очередь на массиве неэффективна?
После нескольких операций
enqueue
иdequeue
, свободные ячейки в начале массива не используются.В итоге массив может казаться «переполненным», хотя там ещё есть пустые позиции.
Пример поведения обычной очереди:
Хотя есть 2 пустые ячейки слева, новые элементы уже нельзя добавить. Это называется ложное переполнение.
Кольцевая Очередь(Circular Queue) решает эту проблему, используя массив по кругу. Идея: после конца массива можно «перейти» снова в начало.
Что такое Circular Queue?
Это оптимизированная версия обычной очереди на массиве фиксированной длины. Она решает проблему «ложного переполнения», когда свободные ячейки в начале массива остаются неиспользованными.
Главная идея: массив рассматривается как замкнутый круг. Если указатель достигает конца массива, он не останавливается, а возвращается к началу.
Таким образом, в кольцевой очереди все ячейки массива могут быть эффективно использованы, и не нужно выполнять сдвиги элементов.
Аналогия из жизни: колесо обозрения

Представьте карусель обозрения с кабинками:
Посетители садятся в свободные кабинки по порядку (enqueue).
Когда круг завершается, первые кабинки подъезжают к выходу, и люди выходят (dequeue).
Кабинки снова становятся свободными и сразу же доступны для новых посетителей.
Так работает Circular Queue: массив используется как «карусель», где начало и конец соединены, и каждое место рано или поздно переиспользуется.
Визуализация поведения Кольцевой очереди:
Зачем учить Circular Queue?
Понимание и реализация Circular Queue важны, потому что наивная очередь на массиве сталкивается с проблемой «ложного переполнения», освободившиеся места в начале массива не используются. Это ведёт к неэффективности и ошибкам.
Освоение техники Circular Queue помогает:
научиться работать с индексами по модулю, что часто встречается в алгоритмах;
увидеть практическое применение в системах с ограниченными ресурсами: сетевые буферы, обработка потоков, очереди задач в реальном времени.
📌 В стандартных библиотеках Java (ArrayDeque
) и Python (collections.deque
) очередь реализована на основе кольцевого буфера (Circular Queue). Поэтому важно освоить эту технику. Она объясняет, как под капотом работают готовые API, и помогает уверенно применять их в реальных задачах.
С концепцией Circular Queue мы ознакомились в предыдущем разделе.
Здесь будут рассмотрены детали реализации: как устроены индексы front
и rear
, как выполняются операции вставки и удаления, и какие ошибки чаще всего возникают.
В этой статье разбираются четыре ключевые ситуации:
Обычная вставка (
enqueue
)Вставка с оборачиванием (
enqueue wrap
)Обычное удаление (
dequeue
)Удаление с оборачиванием (
dequeue wrap
)
1. Enqueue: вставка элемента
Обычная вставка (regular enqueue)
Если хвост (rear
) ещё не дошёл до конца массива, вставка выполняется в следующую позицию.

Вставка с Оборачиванием (wrap-around enqueue)
Если rear
находится в конце массива, но в начале есть свободные ячейки (после удалений), хвост «оборачивается» и продолжает вставку с начала.

Псевдокод
Dequeue: удаление элемента
Обычное удаление (regular dequeue)
Если front
меньше rear
, элемент удаляется напрямую, а голова сдвигается вправо.

Удаление с Оборачиванием (wrap-around dequeue)
Если front
достиг конца массива, после удаления он должен «обернуться» и начать снова с начала массива.

Псевдокод
LeetCode Задачи:
Совет
В технике Circular Queue ключ к правильной работе является контроль индексов и понимание циклического движения по массиву:
При вставке (enqueue): индекс
rear
всегда смещается по модулю длины массива:(rear + 1) % capacity
. Это предотвращает выход за границы и обеспечивает «оборачивание».При удалении (dequeue): аналогично обновляется
front
:(front + 1) % capacity
. После удаления последнего элемента оба индекса нужно сбросить в-1
.Условие переполнения: корректное сравнение:
(rear + 1) % capacity == front
. Простоеfront == rear
приводит к ложному срабатыванию.FIFO сохраняется только при разделении ролей:
front
отвечает за удаление,rear
за вставку. Их путаница ломает очередь.
Эта реализация основана на массиве и показывает, как эффективно переиспользовать ограниченную память.
Также Circular Queue можно реализовать на связанном списке(LinkedList), но у такого подхода есть недостаток: он требует дополнительной памяти для ссылок и теряет преимущество компактности массива.
Результат
Понимание и реализация всех четырёх случаев Circular Queue Technique помогает:
полностью освоить принцип повторного использования памяти;
уверенно работать с индексами и арифметикой по модулю;
понимать внутреннюю реализацию очередей в
ArrayDeque
(Java) иcollections.deque
(Python);легко переходить к более сложным структурам: Deque, Ring Buffer, Blocking Queue.