Подтвердить что ты не робот

Изменить приоритетQueue на максимальный приоритет

У меня есть очередь приоритетов в Java целых чисел:

 PriorityQueue<Integer> pq= new PriorityQueue<Integer>();

Когда я вызываю pq.poll(), я получаю минимальный элемент.

Вопрос: как изменить код, чтобы получить максимальный элемент?

4b9b3361

Ответ 1

Как об этом:

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 до их естественного порядка в этом случае.

Ответ 2

Вы можете использовать лямбда-выражение с 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>. (Это используется на месте, в отличие от анонимного класса или дискретной реализации.)

Ответ 3

Вы можете предоставить пользовательский объект 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;
    }
});

Теперь очередь приоритетов изменит все ее сравнения, поэтому вы получите максимальный элемент, а не минимальный элемент.

Надеюсь, это поможет!

Ответ 4

PriorityQueue<integer> pq = new PriorityQueue<integer> (
  new Comparator<integer> () {
    public int compare(Integer a, Integer b) {
       return b - a;
    }
  }
);

Ответ 5

Элементы очереди приоритетов упорядочены в соответствии с их естественным порядком или с помощью компаратора, предоставленного во время построения очереди.

Компаратор должен переопределить метод сравнения.

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()

Ответ 6

Вот пример 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

Ответ 7

Вы можете использовать MinMaxPriorityQueue (это часть библиотеки Guava): здесь документация. Вместо poll() вам нужно вызвать метод pollLast().

Ответ 8

Вы можете попробовать нажать элементы с обратным знаком. Например: добавить a = 2 и b = 5, а затем опросить b = 5.

PriorityQueue<Integer>  pq = new PriorityQueue<>();
pq.add(-a);
pq.add(-b);
System.out.print(-pq.poll());

Как только вы опросите голову очереди, отмените знак для вашего использования. Это напечатает 5 (более крупный элемент). Может использоваться в наивных реализациях. Определенно не надежное решение. Я не рекомендую его.

Ответ 9

Я только что провел симуляцию Монте-Карло на обоих компараторах по двойной куче сортировки 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;
    }
});

Ответ 10

Вы можете попробовать что-то вроде:

PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> -1 * Integer.compare(x, y));

Что работает для любой другой сравнительной функции базы, которую вы могли бы использовать.