Открыть сервис

Очередь (структура данных)

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

Основные операции

Над очередью определены следующие фундаментальные операции:

История и происхождение

Понятие очереди как структуры данных возникло в ранние годы развития программирования, в первую очередь в связи с необходимостью организации буферизации данных и управления задачами в операционных системах. Одним из первых практических применений очередей стали алгоритмы планирования процессов, где они использовались для реализации дисциплины FIFO (First-Come, First-Served — «первым прибыл — первым обслужен»). Теоретическое обоснование и формализация очереди как абстрактного типа данных (ADT) были выполнены в рамках развития теории алгоритмов и структур данных в середине XX века, в частности в работах таких учёных, как Дональд Кнут.

Реализации

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

На основе массива

Реализация очереди с использованием статического или динамического массива является одной из самых простых. Для эффективного использования памяти часто применяется кольцевой буфер (циклический массив), в котором указатели на начало и конец очереди «зациклены»: при достижении последней ячейки массива следующий элемент записывается в первую ячейку (при условии, что она свободна). Это позволяет избежать необходимости сдвигать все элементы при удалении из начала.

Преимущества:

Недостатки:

На основе связного списка

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

Преимущества:

Недостатки:

На основе двух стеков

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

Преимущества:

Недостатки:

Виды очередей

Помимо классической линейной очереди, существуют различные её модификации, расширяющие функциональность.

Очередь с приоритетом

В очереди с приоритетом (Priority Queue) каждый элемент имеет ассоциированный с ним приоритет. Элементы извлекаются не в порядке поступления, а в порядке возрастания (или убывания) приоритета. Если два элемента имеют одинаковый приоритет, порядок их извлечения может быть произвольным или определяться дополнительными правилами (например, по времени поступления). Реализуется обычно на основе кучи (heap) или бинарного дерева поиска.

Двусторонняя очередь (Дек)

Дек (Deque, Double-Ended Queue) — это структура данных, в которой добавление и удаление элементов возможно как с начала, так и с конца. Дек объединяет свойства очереди и стека. Он может быть реализован как на основе массива (кольцевого буфера), так и на основе двусвязного списка.

Циклическая очередь

Циклическая очередь (Circular Queue) — это реализация очереди на основе массива, в которой логически начало и конец очереди соединены, образуя кольцо. Это позволяет эффективно использовать память, не сдвигая элементы при удалении из начала. При достижении последней ячейки массива указатель хвоста переходит на первую ячейку, если она свободна.

Блокирующая очередь

Блокирующая очередь (Blocking Queue) — это очередь, используемая в многопоточных приложениях, которая поддерживает синхронизацию доступа. Если поток пытается извлечь элемент из пустой блокирующей очереди, он приостанавливается (блокируется) до тех пор, пока другой поток не добавит элемент. Аналогично, если поток пытается добавить элемент в полную очередь, он блокируется до освобождения места. Широко применяется в архитектурах «производитель-потребитель» (Producer-Consumer).

Применение

Очереди являются фундаментальной структурой данных и находят применение в самых разных областях информатики и программирования:

Интересные факты

Источники

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →