Очередь с приоритетом (программирование)Очередь с приоритетом (англ. priority queue) — абстрактный тип данных в программировании, поддерживающий две обязательные операции — добавить элемент и извлечь максимум[1] (минимум). Предполагается, что для каждого элемента можно вычислить его приоритет — действительное число или в общем случае элемент линейно упорядоченного множества[2]. ОписаниеОсновные методы, реализуемые очередью с приоритетом, следующие[2][3][1]:
При этом меньшее значение ключа соответствует более высокому приоритету. В некоторых случаях более естественен рост ключа вместе с приоритетом. Тогда второй метод можно назвать Есть ряд реализаций, в которых обе основные операции выполняются в худшем случае за время, ограниченное (см. «O» большое и «o» малое), где — количество хранимых пар. ПримерыВ качестве примера очереди с приоритетом можно рассмотреть список задач работника. Когда он заканчивает одну задачу, он переходит к очередной — самой приоритетной (ключ будет величиной, обратной приоритету) — то есть выполняет операцию извлечения максимума. Начальник добавляет задачи в список, указывая их приоритет, то есть выполняет операцию добавления элемента. Расширения очереди с приоритетомНа практике интерфейс очереди с приоритетом нередко расширяют другими операциями[4][3]:
В индексированных очередях с приоритетом (адресуемых[5]) возможно обращение к элементам по индексу. Такие очереди могут быть использованы, например, для слияния нескольких отсортированных последовательностей (multiway merge)[1]. Могут также рассматриваться очереди с приоритетом с двусторонним доступом (англ. double-ended priority queue, DEPQ), в которых есть операции доступа как к минимальному, так и к максимальному элементу[6]. РеализацииОчередь с приоритетами может быть реализована на основе различных структур данных. Простейшие (и не очень эффективные) реализации могут использовать неупорядоченный или упорядоченный массив, связный список, подходящие для небольших очередей. При этом вычисления могут быть как «ленивыми» (тяжесть вычислений переносится на извлечение элемента), так и ранними (eager), когда вставка элемента сложнее его извлечения. То есть, одна из операций может быть произведена за время , а другая — в худшем случае за , где — длина очереди[1]. Более эффективными являются реализации на основе кучи, где обе операции можно производить в худшем случае за время [1]. К ним относятся двоичная куча, биномиальная куча, фибоначчиева куча, pairing heap[англ.][6]. Абстрактный тип данных (АТД) для очереди с приоритетом получается из АТД кучи переименованием соответствующих функций. Минимальное (максимальное) значение находится всегда на вершине кучи[7]. Пример на PythonСтандартная библиотека Python содержит модуль # импорт двух функций очереди под именами, принятыми в данной статье
from heapq import heappush as insert, heappop as extract_maximum
pq = [] # инициализация списка
insert(pq, (4, 0, "p")) # вставка в очередь элемента "p" с индексом 0 и приоритетом 4
insert(pq, (2, 1, "e"))
insert(pq, (3, 2, "a"))
insert(pq, (1, 3, "h"))
# вывод четырёх элементов в порядке возрастания приоритетов
print(extract_maximum(pq)[-1] + extract_maximum(pq)[-1] + extract_maximum(pq)[-1] + extract_maximum(pq)[-1])
Этот пример выведет слово «heap». Примечания
Литература
Ссылки
|
Portal di Ensiklopedia Dunia