Опубликован: 26.09.2006 | Доступ: свободный | Студентов: 1801 / 486 | Оценка: 4.25 / 4.12 | Длительность: 17:09:00
ISBN: 978-5-9556-0066-6
Специальности: Программист, Математик
Лекция 4:

Приоритетные очереди

< Лекция 3 || Лекция 4: 123456 || Лекция 5 >

Основные определения

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

  • ВСТАВИТЬ в множество новый элемент со своим ключом.
  • НАЙТИ в множестве элемент с минимальным ключом. Если элементов с минимальным ключом несколько, то находится один из них. Найденный элемент не удаляется из множества.
  • УДАЛИТЬ из множества элемент с минимальным ключом. Если элементов с минимальным ключом несколько, то удаляется один из них.

Дополнительные операции над приоритетными очередями:

  • ОБЪЕДИНИТЬ два множества в одно.
  • УМЕНЬШИТЬ ключ указанного элемента множества на заданное положительное число.

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

Приоритетную очередь можно представить с помощью массива или списка элементов, но такие реализации неэффективны по времени выполнения основных операций. Так, например, поиск элемента с минимальным ключом в неупорядоченном массиве или списке требует последовательного просмотра всех его элементов. Если поддерживать упорядоченность массива или списка по ключу, то "неудобной" окажется операция вставки нового элемента.

Чаще всего приоритетная очередь представляется с помощью корневого дерева или набора корневых деревьев с определенными свойствами. При этом узлам дерева ставятся во взаимно однозначное соответствие элементы рассматриваемого множества.

Соответствие между узлами дерева и элементами множества называется кучеобразным, если для каждого узла i соблюдается следующее условие:

Ключ элемента, приписанного узлу i, не превосходит ключей, приписанных его потомкам.

Такие представления взвешенных множеств называются кучами. Вид дерева и способ его представления в памяти компьютера подбирается в зависимости от тех операций, которые предполагается выполнять над множеством, и от того, насколько эти операции сказываются на суммарной трудоемкости алгоритма.

Представление приоритетной очереди с помощью d-кучи

Представление приоритетной очереди с помощью d -кучи основано на использовании так называемых завершенных d -арных деревьев ( {d \ge 2} ).

Завершенное d -арное дерево — это корневое дерево со следующими свойствами:

  1. Каждый внутренний узел (то есть узел, не являющийся листом дерева), за исключением, быть может, только одного, имеет ровно d потомков. Один узел-исключение может иметь от 1 до d - 1 потомков.
  2. Если k — глубина дерева, то для любого i = 1\dts
k - 1 такое дерево имеет ровно d^i узлов глубины i.
  3. Количество узлов глубины k в дереве глубины k может варьироваться от 1 до d^k. Это свойство является следствием первых двух.

Узлы завершенного d -арного дерева принято нумеровать следующим образом: корень получает номер 0, потомки узла с номером i получают номера: i\cdot d + 1, i\cdot d + 2, \ldots, i\cdot d + d. Такая нумерация удобна тем, что позволяет разместить узлы дерева в массиве в порядке возрастания их номеров, при этом позиции потомков любого узла в массиве легко вычисляются по позиции самого узла. Так же легко по позиции узла вычислить позицию его родителя. Так, для узла, расположенного в позиции i, родительский узел располагается в позиции (i - 1) \mathop{\rm div} d, где \mathop{\rm
div} — операция деления нацело.

В изображении завершенного d -арного дерева узлы одинаковой глубины удобно располагать на одном уровне, при этом потомки одного узла располагаются слева направо в порядке объявленных номеров. При таком рисовании нижний уровень заполняется, возможно, не полностью.

Отметим некоторые простые утверждения о завершенных d -арных деревьях, которые будут полезны при анализе трудоемкости основных операций.

Утверждение 1. Длина h пути из корня завершенного d -арного дерева с n > 1 узлами в любой лист удовлетворяет неравенствам:

\eq*{
\log_d n - 1 < h < \log_d n + 1.
}

Доказательство Минимальное количество узлов в d -куче высоты h ( h > 0 ), по свойствам 2 и 3 d -арного дерева, очевидно, равно 1 + d + d^2 + \ldots + d^{h - 1} +
1 (последний уровень содержит лишь один узел).

Максимальное количество узлов в такой d -куче равно 1 + d
+ d^2 + \ldots + d^h (последний уровень содержит d^h узлов). Отсюда имеем неравенства:

\eq*{
(1 + d + d^2 + \ldots + d^h - 1 + 1) \le n \le (1 + d + d^2 + \ldots + d^h).
}

Суммируя левую и правую части как геометрические прогрессии, получим

\eq*{
(d^h - 1)/(d - 1) + 1 \le n \le (d^{h + 1} - 1)/(d - 1),
}
и после некоторых очевидных оценок с помощью логарифмирования получаем требуемые неравенства:
\eq*{
\log_d n - 1 < h < \log_d n + 1.
}

Утверждение 2. Количество узлов высоты h не превосходит n/d^h.

Под высотой узла понимается расстояние от него до наиболее далекого потомка. Кучу, содержащую n элементов, будем представлять двумя массивами — a[0 \ldots n - 1] и {\rm key}[0 \ldots n
- 1], — полагая что a[i] — имя элемента, приписанного узлу i ; {\rm key}[i] — его ключ. Иногда под a[i] удобно понимать сам элемент исходного множества или ссылку на него. В некоторых прикладных задачах нет необходимости помещать в приоритетную очередь ни сами элементы, ни их имена, в таких случаях при организации кучи используется лишь массив {\rm key}[0 \ldots n - 1].

На рис. 4.1 приведен пример кучи для d = 3, n = 18. Кружочками изображены узлы дерева, в них записаны элементы массива, представляющие имена элементов кучи.

Пример кучи при d = 3, n = 7 для приоритетной очереди, содержащей элементы с ключами 1, 2, 2, 2, 3, 4, 5, изображен на рис. 4.2, где пара чисел в каждом кружочке обозначает номер узла и ключ соответствующего элемента.


Рис. 4.1.

Рис. 4.2.
< Лекция 3 || Лекция 4: 123456 || Лекция 5 >
Антон Сиротинкин
Антон Сиротинкин

на стр 6, лекции 3, Очевидно "Ck <= модуль(Gk(е))*b(k+1)" (1) - , подскажите что значит "модуль" и почему это очевидно...