将 priorityQueue 更改为 max priorityQueue

我在 Java 的整数中有优先级队列:

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

当我调用 pq.poll()时,我得到最小元素。

问: 如何更改代码以获得最大元素?

308050 次浏览

您可以提供一个自定义 Comparator对象,按照相反的顺序对元素进行排序:

PriorityQueue<Integer> pq = new PriorityQueue<Integer>(defaultSize, new Comparator<Integer>() {
public int compare(Integer lhs, Integer rhs) {
if (lhs < rhs) return +1;
if (lhs.equals(rhs)) return 0;
return -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中的元素进行排序。

你可以使用 MinMaxPriorityQueue(它是番石榴库的一部分) : 下面是文档

下面是 Java 中的 Max-Heap 示例:

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

我刚刚运行了一个蒙特卡罗模拟对两个比较器的双堆排序最小最大值,他们都得到了相同的结果:

这些是我使用过的最大比较器:

(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<Integer> (
new Comparator<Integer> () {
public int compare(Integer a, Integer b) {
return b - a;
}
}
);

你可以尝试用逆符号推元素。例如: 添加 a = 2 & b = 5,然后轮询 b = 5。

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

一旦您轮询了队列的头部,就反转您使用的符号。 这将打印5(较大的元素)。可以在初始实现中使用。绝对不可靠。我不建议这么做。

从 Java8开始就可以使用 lambda 表达式。

下面的代码将打印10,较大的。

// There is overflow problem when using simple lambda as comparator, as pointed out by Фима Гирин.
// PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> y - x);


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


pq.add(10);
pq.add(5);
System.out.println(pq.peek());

Lambda 函数将两个 Integer 作为输入参数,相互减去它们,然后返回算术结果。Lambda 函数实现 Functional Interface,Comparator<T>。(与匿名类或离散实现相反,这种方法是适当使用的。)

优先级队列的元素按照它们的自然顺序排序,或者按照队列构造时提供的比较器排序。

比较器应重写比较方法。

int compare(T o1, T o2)

当第一个参数小于、等于或大于第二个参数时,默认比较方法返回负整数、零或正整数。

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

你可以试试这样:

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

它适用于您可能拥有的任何其他基本比较函数。

这可以通过下面的 Java8代码实现,该代码引入了一个只使用比较器的构造函数。

PriorityQueue<Integer> maxPriorityQ = new PriorityQueue<Integer>(Collections.reverseOrder());
PriorityQueue<Integer> lowers = new PriorityQueue<>((o1, o2) -> -1 * o1.compareTo(o2));

将 PriorityQueue 更改为 MAX PriorityQueue 方法1: Queue pq = new PriorityQueue < > (Collections.verseOrder ()) ; 方法2: 队列 pq1 = new PriorityQueue < > ((a,b)-> b-a) ; 让我们来看几个例子:

public class Example1 {
public static void main(String[] args) {


List<Integer> ints = Arrays.asList(222, 555, 666, 333, 111, 888, 777, 444);
Queue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
pq.addAll(ints);
System.out.println("Priority Queue => " + pq);
System.out.println("Max element in the list => " + pq.peek());
System.out.println("......................");
// another way
Queue<Integer> pq1 = new PriorityQueue<>((a, b) -> b - a);
pq1.addAll(ints);
System.out.println("Priority Queue => " + pq1);
System.out.println("Max element in the list => " + pq1.peek());
/* OUTPUT
Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222]
Max element in the list => 888
......................
Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222]
Max element in the list => 888


*/




}
}

我们来做个著名的采访吧 问题: 使用 PriorityQueue 的数组中的第 Kth 最大元素

public class KthLargestElement_1{
public static void main(String[] args) {


List<Integer> ints = Arrays.asList(222, 555, 666, 333, 111, 888, 777, 444);
int k = 3;
Queue<Integer> pq = new PriorityQueue<>(Collections.reverseOrder());
pq.addAll(ints);
System.out.println("Priority Queue => " + pq);
System.out.println("Max element in the list => " + pq.peek());
while (--k > 0) {
pq.poll();
} // while
System.out.println("Third largest => " + pq.peek());
/*
Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222]
Max element in the list => 888
Third largest => 666


*/
}
}

另一种方式:

public class KthLargestElement_2 {
public static void main(String[] args) {
List<Integer> ints = Arrays.asList(222, 555, 666, 333, 111, 888, 777, 444);
int k = 3;


Queue<Integer> pq1 = new PriorityQueue<>((a, b) -> b - a);
pq1.addAll(ints);
System.out.println("Priority Queue => " + pq1);
System.out.println("Max element in the list => " + pq1.peek());
while (--k > 0) {
pq1.poll();
} // while
System.out.println("Third largest => " + pq1.peek());
/*
Priority Queue => [888, 444, 777, 333, 111, 555, 666, 222]
Max element in the list => 888
Third largest => 666


*/
}
}

正如我们所看到的,两者给出了相同的结果。

这可以通过使用

PriorityQueue<Integer> pq = new PriorityQueue<Integer>(Collections.reverseOrder());

在 Java8 + 中,您可以通过以下方法之一创建一个最大优先级队列:

方法一:

PriorityQueue<Integer> maxPQ = new PriorityQueue<>(Collections.reverseOrder());

方法二:

PriorityQueue<Integer> maxPQ = new PriorityQueue<>((a,b) -> b - a);

方法三:

PriorityQueue<Integer> maxPQ = new PriorityQueue<>((a,b) -> b.compareTo(a));

我们可以通过创建 定制比较器类来做到这一点,该类实现了 Compaator 接口,并重写了其比较方法。下面是相同的代码:

import java.util.PriorityQueue;
import java.util.Comparator;
public class Main
{
public static void main(String[] args) {
PriorityQueue<Integer> nums = new PriorityQueue<>(new CustomComparator());
nums.offer(21);
nums.offer(1);
nums.offer(8);
nums.offer(2);
nums.offer(-4);
System.out.println(nums.peek());
}
}
class CustomComparator implements Comparator<Integer>{
@Override
public int compare(Integer n1, Integer n2){
int val = n1.compareTo(n2);
if(val > 0)
return -1;
else if(val < 0)
return 1;
else
return 0;
}
}

使用 lamba,只需将结果与 -1相乘即可得到最大优先级队列。

PriorityQueue<> q = new PriorityQueue<Integer>(
(a,b) ->  -1 * Integer.compare(a, b)
);
  • 在 java 中使用 < strong > Collections.VERseOrder () 反向 PriorityQueue 的简单方法。

- > 我有优先队列: (喜欢:)

    PriorityQueue<String> pQueue = new PriorityQueue<>();
    

pQueue.add("Honda");
pQueue.add("Passion");
pQueue.add("Heroni");
pQueue.add("Ola");

- > 为反向数组存储创建新的优先级队列。

  PriorityQueue<String> pRqueue = new
PriorityQueue<String>(pQueue.size(), Collections.reverseOrder());

> 在 Syntex < strong > pQueue.size () 中是已声明的数组。 所以,给这里只有大小。

- > 将旧队列的元素添加到新队列中:

  pRqueue.addAll(pQueue);

- > ,现在打印队列。输出显示如下:

    Queue Element:[ Heroni, Ola, Honda, Passion ]
Reverese PriorityQueue Element:[ Passion, Ola, Honda, Heroni ]

完成。保留代码。

我提到了实现这一目标的5种方法:

  1. 使用 compareTo()方法
   PriorityQueue<Integer> pq = new PriorityQueue<>((o1, o2) -> o2.compareTo(o1));
  1. 使用 compare()方法
   PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> Integer.compare(y, x));
  1. 使用自定义 Comparator方法
   PriorityQueue<Integer> pq = new PriorityQueue<>(new CustomIntegerComparator());


static class CustomIntegerComparator implements Comparator<Integer> {


@Override
public int compare(Integer o1, Integer o2) {
return o1 < o2 ? 1 : -1;
}
}
  1. 使用 Collection方法
    PriorityQueue<Integer> pq= new PriorityQueue<>(Collections.reverseOrder());
  1. 使用 Arrow(Lambda表达式)函数
    PriorityQueue<Integer> pq= new PriorityQueue<>((a, b) -> b - a);
  1. 使用自定义 Comparator方法(通过差异)
   PriorityQueue<Integer> pq = new PriorityQueue<> (new Comparator<Integer> ()
{
public int compare(Integer a, Integer b)
{
return b - a;
}
});

你可以参考这里给出的其他答案。如果你想要一个非常简单的黑客为此,只是尊敬的数字符号。 假设我想在队列中输入5和10,

PriorityQueue<Integer> pq= new PriorityQueue<Integer>();
pq.add(-5);
pr.add(-10);

因为优先级队列默认实现了 Java 中的最小堆,所以您可以使用这种逻辑来实现最大堆。