Без переопределения очереди приоритетов самостоятельно (поэтому, используя только utils.PriorityQueue
), у вас есть два основных подхода:
1) Снимаем и ставим обратно
Удалите элемент, затем верните его с новым приоритетом. Это объясняется в ответах выше. Удаление элемента - O (n), поэтому этот подход довольно медленный.
2) Используйте карту и держите устаревшие элементы в очереди
Оставьте HashMap
элемента - ›приоритет. Ключи карты - это элементы (без их приоритета), а значения карты - это приоритеты.
Синхронизируйте его с PriorityQueue (т.е. каждый раз, когда вы добавляете или удаляете элемент из очереди, обновляйте карту соответствующим образом).
Теперь, когда вам нужно изменить приоритет элемента, просто добавьте тот же элемент в очередь с другим приоритетом. Когда вы опрашиваете элемент из очереди, проверьте, совпадает ли его приоритет с приоритетом вашей карты. Если нет, то откажитесь от этого и снова проведите опрос.
Если вам не нужно слишком часто менять приоритеты, второй подход будет более быстрым. Ваша куча будет больше, и вам, возможно, придется опрашивать больше раз, но вам не нужно искать свой предмет. Операция изменения приоритета будет иметь вид O (f (n) log n *), где f (n) - количество операций изменения приоритета на каждый item и n * фактический размер вашей кучи (который равен n * f (n)).
Я считаю, что если f (n) равно O (n / logn) (например, f (n) = O (sqrt (n)), это быстрее, чем первый подход.
Примечание: в приведенном выше объяснении под приоритетом я имею в виду все переменные, которые используются в вашем компараторе. Также ваш элемент должен реализовывать equals
и hashcode
, и оба метода не должны использовать переменные приоритета.
person
Ricola
schedule
06.06.2021