Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Data Structures and Algorithms in C++ 2e (На ру...docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.37 Mб
Скачать

Глава 8. Кучи и приоритетные очереди

8.3.3 Осуществление приоритетной очереди с кучей

Мы теперь обсуждаем, как осуществить приоритетную очередь, использующую кучу. Наше основанное на куче

представление для приоритетной очереди P состоит из следующего (см. рисунок 8.6):

куча: полное двоичное дерево T, чьи узлы хранят элементы очереди

и чьи ключи удовлетворяют собственность заказа кучи. Мы принимаем двоичное дерево T

осуществлен, используя вектор, как описано в Разделе 8.3.2. Для каждого узла v T, мы обозначаем связанный ключ k (v).

аккомпанемент: компаратор, который определяет полное отношение заказа среди ключей.

Рисунок 8.6: Иллюстрация основанного на куче внедрения приоритетной очереди.

С этой структурой данных, размером функций и пустым взятием O (1) время, как обычно. Кроме того, минута функции может также быть легко выполнена в O (1) время, получая доступ к входу, сохраненному в корне кучи (который является в индексе 1 в векторе).

Вставка

Давайте рассмотрим, как выполнить вставку на приоритетной очереди, осуществленной с a

куча T. Чтобы сохранить новый элемент e в T, мы добавляем, что новый узел z к T с операцией добавляет, так, чтобы этот новый узел стал последним узлом T, и затем сохраните e в этом узле.

После этого действия дерево T полно, но это может нарушить опору заказа кучи - erty. Следовательно, если узел z не является корнем T (то есть, приоритетная очередь была пуста перед вставкой), мы сравниваем ключ k (z) с ключом k (u) сохраненный в родителе

u z. Если k (z)³ k (u), собственность заказа кучи удовлетворена и алгоритм трижды -

minates. Если вместо этого k (z) <k (u), то мы должны восстановить собственность заказа кучи,

который может быть в местном масштабе достигнут, обменяв записи, сохраненные в z и u. (См. Фигу - ures 8.7 (c) и (d).) Этот обмен заставляет новый вход (k, e) перемещать один уровень вверх. Снова, собственность заказа кучи может быть нарушена, и мы продолжаем обмениваться, идти

8.3. Кучи 345

(a) (b)

(c) (d)

(e) (f)

(g) (h)

Рисунок 8.7: Вставка нового входа с ключевыми 2 в кучу Figure8.6: (a) начальная куча; (b) после выступающей операции добавляют; (c) и (d) обмениваются, чтобы в местном масштабе восстановить собственность частичного порядка; (e) и (f) другой обмен; (g) и (h) заключительный обмен.

346

Глава 8. Кучи и Приоритет Стоят в очереди в t, пока никакое нарушение собственности заказа кучи не происходит. (См. Figures8.7 (e) и (h).)

Восходящее движение недавно вставленного входа посредством обменов - довод «против» - ventionally названное пузырение-кучи. Обмен или решает нарушение собственности заказа кучи или размножает его, каждый выравнивает в куче. В худшем случае - куча, пузырящаяся, заставляет новый вход перемещать полностью до корня кучи T. (См. рисунок 8.7.) Таким образом, в худшем случае, число обменов выступило в

выполнение вставки функции равно высоте T, то есть, это -⌊log n

Суждение 8.5.

Удаление

Давайте теперь повернемся к функции removeMin приоритетной очереди ADT. Алгоритм

для выполнения функции removeMin использование кучи T иллюстрирован в рисунке 8.8.

Мы знаем, что элемент с самым маленьким ключом сохранен в корне r T (даже если есть больше чем один вход с самым маленьким ключом). Однако, если r не единственный узел T, мы не можем просто удалить узел r, потому что это действие разрушило бы структуру двоичного дерева. Вместо этого мы получаем доступ к последнему узлу w T, копируем его вход в корень r, и затем удаляем последний узел, выполняя операцию, удаляют полного двоичного дерева ADT. (См. рисунок 8.8 (a) и (b).)

Вниз-куча, Пузырящаяся после Удаления

Мы не обязательно сделаны, однако, поскольку, даже при том, что T теперь полон, T может

теперь нарушьте собственность заказа кучи. Если у T есть только один узел (корень), то собственность заказа кучи тривиально удовлетворена, и алгоритм заканчивается. Иначе, мы отличаем два случая, где r обозначает корень T:

• Если у r нет правильного ребенка, позвольте s быть покинутым ребенком r

• Иначе (r имеет обоих детей), позвольте s быть ребенком r с меньшим ключом

Если k (r)£ k (s), собственность заказа кучи удовлетворена, и алгоритм заканчивается.

Если вместо этого k (r)> k (s), то мы должны восстановить собственность заказа кучи, которая может

будьте в местном масштабе достигнуты, обменяв записи, сохраненные в r и s. (См. рисунок 8.8 (c) и (d).) (Отмечают, что мы не должны обменивать r с родным братом s.) Обмен, который мы выполняем, восстанавливает собственность заказа кучи для узла r и его детей, но это может нарушить эту собственность в s; следовательно, нам, вероятно, придется продолжить обмениваться вниз T, пока никакое нарушение собственности заказа кучи не происходит. (См. рисунок 8.8 (e) и (h).)

Этот нисходящий процесс обмена называют пузырением вниз-кучи. Обмен или решает нарушение собственности заказа кучи или размножает его, каждый уравнивает в куче. В худшем случае вход двигается полностью вниз в нижний уровень. (См. рисунок 8.8.) Таким образом число обменов выступило в выполнении функции

removeMin, в худшем случае, равном высоте кучи T, то есть, это -⌊log n ⌋

Суждением 8.5