У меня есть очередь приоритетов в Java целых чисел:
PriorityQueue<Integer> pq= new PriorityQueue<Integer>();
Когда я вызываю pq.poll()
, я получаю минимальный элемент.
Вопрос: как изменить код, чтобы получить максимальный элемент?
У меня есть очередь приоритетов в Java целых чисел:
PriorityQueue<Integer> pq= new PriorityQueue<Integer>();
Когда я вызываю pq.poll()
, я получаю минимальный элемент.
Вопрос: как изменить код, чтобы получить максимальный элемент?
Как об этом:
PriorityQueue<Integer> queue = new PriorityQueue<>(10, Collections.reverseOrder());
queue.offer(1);
queue.offer(2);
queue.offer(3);
//...
Integer val = null;
while( (val = queue.poll()) != null) {
System.out.println(val);
}
Collections.reverseOrder()
предоставляет Comparator
, который сортировал бы элементы в PriorityQueue
в порядке oposite до их естественного порядка в этом случае.
Вы можете использовать лямбда-выражение с Java 8.
Следующий код будет печатать 10, чем больше.
PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> y - x);
pq.add(10);
pq.add(5);
System.out.println(pq.peek());
Лямбда-функция будет принимать два целых числа в качестве входных параметров, вычитать их друг от друга и возвращать арифметический результат. Лямбда-функция реализует функциональный интерфейс Comparator<T>
. (Это используется на месте, в отличие от анонимного класса или дискретной реализации.)
Вы можете предоставить пользовательский объект Comparator
, который занимает место в обратном порядке:
PriorityQueue<Integer> pq = new PriorityQueue<Integer>(defaultSize, new Comparator<Integer>() {
int compare(Integer lhs, Integer rhs) {
if (lhs > rhs) return +1;
if (lhs.equals(rhs)) return 0;
return -1;
}
});
Теперь очередь приоритетов изменит все ее сравнения, поэтому вы получите максимальный элемент, а не минимальный элемент.
Надеюсь, это поможет!
PriorityQueue<integer> pq = new PriorityQueue<integer> (
new Comparator<integer> () {
public int compare(Integer a, Integer b) {
return b - a;
}
}
);
Элементы очереди приоритетов упорядочены в соответствии с их естественным порядком или с помощью компаратора, предоставленного во время построения очереди.
Компаратор должен переопределить метод сравнения.
int compare(T o1, T o2)
Метод сравнения по умолчанию возвращает отрицательное целое число, ноль или положительное целое число, поскольку первый аргумент меньше, равен или больше второго.
Приоритет PriorityQueue, предоставляемый Java, - это Min-Heap, если вы хотите, чтобы максимальная куча была следующим кодом
public class Sample {
public static void main(String[] args) {
PriorityQueue<Integer> q = new PriorityQueue<Integer>(new Comparator<Integer>() {
public int compare(Integer lhs, Integer rhs) {
if(lhs<rhs) return +1;
if(lhs>rhs) return -1;
return 0;
}
});
q.add(13);
q.add(4);q.add(14);q.add(-4);q.add(1);
while (!q.isEmpty()) {
System.out.println(q.poll());
}
}
}
Ссылка: https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html#comparator()
Вот пример Max-Heap в Java:
PriorityQueue<Integer> pq1= new PriorityQueue<Integer>(10, new Comparator<Integer>() {
public int compare(Integer x, Integer y) {
if (x < y) return 1;
if (x > y) return -1;
return 0;
}
});
pq1.add(5);
pq1.add(10);
pq1.add(-1);
System.out.println("Peek: "+pq1.peek());
Выход будет 10
Вы можете использовать MinMaxPriorityQueue
(это часть библиотеки Guava):
здесь документация. Вместо poll()
вам нужно вызвать метод pollLast()
.
Вы можете попробовать нажать элементы с обратным знаком. Например: добавить a = 2 и b = 5, а затем опросить b = 5.
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.add(-a);
pq.add(-b);
System.out.print(-pq.poll());
Как только вы опросите голову очереди, отмените знак для вашего использования. Это напечатает 5 (более крупный элемент). Может использоваться в наивных реализациях. Определенно не надежное решение. Я не рекомендую его.
Я только что провел симуляцию Монте-Карло на обоих компараторах по двойной куче сортировки min max, и оба они пришли к одному и тому же результату:
Это максимальные компараторы, которые я использовал:
(A) Сборник встроенного компаратора
PriorityQueue<Integer> heapLow = new PriorityQueue<Integer>(Collections.reverseOrder());
(B) Пользовательский компаратор
PriorityQueue<Integer> heapLow = new PriorityQueue<Integer>(new Comparator<Integer>() {
int compare(Integer lhs, Integer rhs) {
if (rhs > lhs) return +1;
if (rhs < lhs) return -1;
return 0;
}
});
Вы можете попробовать что-то вроде:
PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> -1 * Integer.compare(x, y));
Что работает для любой другой сравнительной функции базы, которую вы могли бы использовать.