Удалите самый большой/самый маленький элемент.
API, которые мы ищем:
* Вставлять
* Удалить
* Найти следующий максимум
Реализации, которые мы можем придумать:
* Неупорядоченный массив: O(1) для вставки, O(N) для удаления, O(N) для поиска следующего максимума
* Упорядоченный массив: O(N) для вставки, O(1) для удаления, O(1) для поиска следующего максимума
* Двоичная куча/полные двоичные деревья: O(logN) для вставки, O(logN) для удаления, O(logN) для поиска следующего максимума
Двоичные кучи:
Двоичные кучи используются в приоритетных очередях. Это в основном потому, что они занимают гораздо меньше места. Хранение и сортировка всех данных для нахождения наибольшего потребует NlogN времени и N пространства.
Порядок в куче: Родительский ключ не меньше, чем дочерние ключи.
Самый большой ключ находится в первом индексе массива.
Родительский узел k находится на k/2
Дочерними элементами узла k являются 2k и 2k+1.
Сценарий 1: Дочерний ключ становится больше, чем ключ его родителя.
Для устранения нарушения:
- Обмен ключа в дочернем с ключом в родительском.
- Повторяйте, пока порядок кучи не восстановится.
Сценарий 2. Родительский ключ становится меньше одного (или обоих) дочернего ключа.
Для устранения нарушения:
- Обмен ключа в родительском с ключом в более крупном дочернем элементе.
- Повторяйте, пока порядок кучи не восстановится.
Как внедрить API Priority Queue?
- Вставка: добавьте узел в конце, а затем поднимите его вверх.
Не более 1 + lg N сравнивает. - Удалить: поменять местами корень с узлом в конце, а затем понизить его.
Не более 2 lg N сравнивается.