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

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

Очередь с приоритетом — это абстрактный тип данных (ADT) в информатике, который моделирует набор элементов, каждый из которых обладает определённым приоритетом. Основная операция очереди с приоритетом — извлечение элемента с наивысшим (или наинизшим, в зависимости от реализации) приоритетом среди всех находящихся в очереди. В отличие от обычной очереди (FIFO — «первым пришёл — первым вышел») или стека (LIFO — «последним пришёл — первым вышел»), порядок извлечения элементов в очереди с приоритетом определяется не временем их добавления, а значением их приоритета. Этот тип данных широко применяется в алгоритмах планирования, симуляции дискретных событий, сжатии данных, поиске кратчайших путей в графах и других задачах, где требуется динамический доступ к наиболее важному объекту.

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

Очередь с приоритетом поддерживает следующий минимальный набор операций:

Дополнительные операции могут включать:

Реализации

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

Двоичная куча (Binary Heap)

Наиболее распространённая реализация. Двоичная куча — это полное бинарное дерево, которое удовлетворяет свойству кучи: для max-кучи каждый родительский элемент имеет приоритет не меньше, чем у его потомков. Обычно реализуется на массиве.

Двоичная куча лежит в основе алгоритма пирамидальной сортировки (heapsort) и является стандартной реализацией очереди с приоритетом во многих языках программирования (например, heapq в Python, PriorityQueue в Java, std::priority_queue в C++).

Биномиальная куча (Binomial Heap)

Представляет собой набор биномиальных деревьев, каждое из которых удовлетворяет свойству кучи. Поддерживает эффективное слияние двух очередей.

Куча Фибоначчи (Fibonacci Heap)

Более сложная структура, обеспечивающая очень быструю вставку и изменение ключа за счёт отложенных операций.

Благодаря быстрой операции decrease_key, куча Фибоначчи применяется в некоторых реализациях алгоритма Дейкстры для поиска кратчайших путей в графах.

Сортирующее дерево (Binary Search Tree)

Любое сбалансированное бинарное дерево поиска (например, красно-чёрное дерево, AVL-дерево) может использоваться как очередь с приоритетом, если хранить элементы с ключом-приоритетом. Однако это избыточно, так как дерево поддерживает множество дополнительных операций, не нужных для очереди.

Неупорядоченный список (Unsorted List)

Простейшая реализация, при которой элементы хранятся в списке без какого-либо порядка.

Упорядоченный список (Sorted List)

Элементы хранятся в отсортированном по приоритету порядке.

Применение

Очередь с приоритетом является ключевым компонентом многих алгоритмов и систем.

Алгоритмы на графах

Планирование процессов (Scheduling)

В операционных системах очереди с приоритетом используются для планирования выполнения процессов и потоков. Процессам с более высоким приоритетом (например, системным задачам) выделяется процессорное время раньше, чем процессам с низким приоритетом.

Дискретно-событийное моделирование

В симуляторах (например, сетевых или производственных) события (наступление момента времени) помещаются в очередь с приоритетом, где приоритетом является время наступления события. Симулятор последовательно извлекает и обрабатывает события в хронологическом порядке.

Сжатие данных (алгоритм Хаффмана)

При построении оптимального префиксного кода (кода Хаффмана) используется очередь с приоритетом для многократного объединения двух символов с наименьшими частотами.

Обработка потоковых данных

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

Игровые движки

В компьютерных играх очереди с приоритетом используются для управления AI-агентами, обработки коллизий, рендеринга объектов в порядке удалённости от камеры и других задач.

Разновидности

Min-heap vs Max-heap

Очередь с приоритетом может быть реализована как max-heap (извлекается элемент с наибольшим приоритетом) или min-heap (извлекается элемент с наименьшим приоритетом). Выбор зависит от задачи. Например, в алгоритме Дейкстры обычно используется min-heap, так как ищется кратчайший путь (наименьшее расстояние).

Статическая vs динамическая

Статическая очередь с приоритетом строится один раз для заданного набора элементов и не поддерживает вставку новых. Динамическая очередь допускает добавление и удаление элементов в произвольном порядке.

С возможностью изменения приоритета

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

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

Источники

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

На главную BFOmetr →