Без каких-либо дополнительных предположений относительно операций, которые вы собираетесь выполнять , вы не сможете добиться лучшей производительности, чем с PriorityQueue
или другим O (log (n)) - вставкой коллекции (TreeSet,например, но вы теряете O (1) -пик).Как вы правильно предположили, Collections.min(Collection, Comparator)
является линейной операцией.
Но зависит от того, как часто вам нужно менять порядок: например, если вам нужно только изменить его время от времении все еще сохраняйте «стандартный» порядок, min()
является жизнеспособным вариантом, но если вам нужно полностью изменить порядок, то вам, вероятно, будет лучше с переупорядочением очереди / набора (то есть обходом и добавлением всех элементов вновый), жесткий по цене O (nlog (n)).Использование Collections.sort(List, Comparator)
может быть эффективным, если вам требуется много переупорядочения по сравнению со вставками, но требует от вас использования List
.
Конечно, если вы можете сделать несколько сильные предположения относительно типов сортировки, вы будетенужно (например, если это может быть ограничено частью данных), вы можете написать свою собственную коллекцию.
Редактировать: Таким образом, у вас есть (более или менее) конечное числоупорядочения (не берите в голову, что это один и тот же тип сравнения по разным полям, это разные компараторы и вот что имеет значение)?Если это так, вы, вероятно, сможете добиться максимальной производительности, используя m очередей, которые ссылаются на одни и те же объекты, каждая из которых использует свой компаратор (самый простой метод, на самом деле).Таким образом, у вас есть:
- постоянный доступ к времени
- O (m * logn (n)) вставок (для вставки в каждую очередь)
- O (m *)n) удаления (для удаления из каждой очереди)
- без затрат на заказ (так как он обрабатывается вставками)
- немного большая стоимость памяти (вероятно, незначительная)
- дополнительная O (n * log (n)) стоимость в первый раз, когда запрошено частичное упорядочение
Предполагая, что значение на m порядков меньше n, это сопоставимо с оптимальной производительностью PriorityQueue для однократного упорядочения.Для удобства вы можете обернуть это в пользовательскую коллекцию, которая принимает параметр Comparator в операциях поиска, и использовать его в качестве ключа для HashMap всех PriorityQueues.
Edit # 2: В этом случае нет лучшего решения, чем запуск min () для каждого поиска (если только вы не можете делать предположения об изменениях данных);это также означает, что лучше использовать ArrayList в качестве коллекции, поскольку он имеет минимально возможную стоимость для каждой операции, и вы в любом случае не будете извлекать выгоду из естественного упорядочивания PriorityQueue.В результате вы получите линейную стоимость при извлечении (за мин) и постоянную при вставке и удалении: это оптимально, поскольку не существует алгоритма сортировки, который в любом случае имел бы меньше Ω (n) и Θ (nlog n).
Как примечание, упорядоченные коллекции работают в предположении, что значения не изменятся после вставки;Это связано с тем, что не существует экономически эффективного способа мониторинга изменений или их изменения "на месте".