На самом деле вы можете без проблем удалить элемент из середины кучи.
Идея состоит в том, чтобы взять последний элемент в куче и, начиная с текущей позиции (т. Е. Позиции, которая удерживалаэлемент, который вы удалили), поднимите его, если новый элемент больше, чем родитель старого элемента.Если он не больше родительского, то просейте его вниз.
Это процедура для максимальной кучи.Конечно, за минимальную кучу вы должны поменять местами большие и меньшие случаи.
Поиск элемента в куче - операция O (n), но если вы уже знаете, гдеон находится в куче, удаляя его O (log n).
Несколько лет назад я опубликовал очередь приоритетов на основе кучи для DevSource.См. Реализация приоритетной очереди в C # .У него есть RemoveAt
метод, который делает именно то, что я описал.
Полный источник в http://www.mischel.com/pubs/priqueue.zip
Обновление
Некоторые спрашивали, возможно ли подняться послеперемещение последнего узла в куче для замены удаленного узла.Рассмотрим эту кучу:
1
6 2
7 8 3
Если вы удалите узел со значением 7, значение 3 заменит его:
1
6 2
3 8
Теперь вам нужно переместить его вверх, чтобы создать правильную кучу:
1
3 2
6 8
Ключевым моментом здесь является то, что если заменяемый элемент находится в другом поддереве, чем последний элемент в куче, возможно, что замещающий узел будет меньше, чем родительский элемент заменяемого узла.