Java的PriorityQueue与min-heap有何不同?

Jef*_*hen 48 java priority-queue

PriorityQueue如果你不能insertWithPriority,他们为什么命名?它看起来非常类似于堆.有什么不同吗?如果没有区别,那为什么它被命名PriorityQueue而不是Heap?

Bin*_*eng 73

默认的PriorityQueue是使用Min-Heap实现的,即top元素是堆中的最小元素.

为了实现max-heap,您可以创建自己的Comparator:

import java.util.Comparator;

public class MyComparator implements Comparator<Integer>
{
    public int compare( Integer x, Integer y )
    {
        return y - x;
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,您可以通过以下方式创建最小堆和最大堆:

PriorityQueue minHeap=new PriorityQueue();
PriorityQueue maxHeap=new PriorityQueue(size, new MyComparator());
Run Code Online (Sandbox Code Playgroud)

  • 确切地说它是一个小堆,因为默认的排序顺序是升序的 (3认同)
  • 更简单的最大堆:`Queue&lt;Integer&gt; maxHeap = new PriorityQueue&lt;Integer&gt;(Collections.reverseOrder());` as [since 1.8](https://docs.oracle.com/javase/8/docs/api/ java/util/PriorityQueue.html),直接传入Comparator,不需要传入初始容量。 (3认同)
  • @Neil 当您使用 Java 8 时,您可以使用 `new PriorityQueue&lt;&gt;(Collections.reverseOrder())`(使用“菱形运算符”)。 (3认同)
  • @ThinkRecursively做一个减号来获取反向比较器是一个糟糕的主意 (2认同)
  • 使用“y - x”作为比较器是错误的,因为它可能会溢出。安全的解决方案“Collections.reverseOrder()”自 Java 1.2 起就存在。 (2认同)

Hen*_*meh 40

对于max-heap,您可以使用:

PriorityQueue<Integer> queue = new PriorityQueue<>(10, Collections.reverseOrder());
Run Code Online (Sandbox Code Playgroud)

  • [从1.8开始](https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html),您可以传入比较器而无需传入初始容量:`Queue &lt;Integer&gt; maxHeap =新的PriorityQueue &lt;Integer&gt;(Collections.reverseOrder());` (2认同)

Mar*_*elo 24

Add()的工作方式类似于insertWithPriority.

您可以使用构造函数定义所需类型的优先级:

PriorityQueue(int, java.util.Comparator)
Run Code Online (Sandbox Code Playgroud)

请查看http://download.oracle.com/javase/1,5.0/docs/api/java/util/PriorityQueue.html

Comparator提供的顺序将代表队列中的优先级.


Gau*_*wat 10

其他答案中描述的默认行为

最小堆(默认):

PriorityQueue<Integer> priorityQueue = new PriorityQueue<>();
Run Code Online (Sandbox Code Playgroud)

对于最大堆:

PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((o1, o2) -> o2-o1);
Run Code Online (Sandbox Code Playgroud)


Mat*_*all 6

PriorityQueueJavaDoc中:

基于优先级堆的无界优先级队列.优先级队列的元素根据其自然顺序排序,或者根据使用的Comparator构造函数在队列构造时提供.

优先级是队列中对象的固有属性.元素是基于某种比较来排序的.要插入具有给定优先级的某个对象,您只需设置对象上的任何字段都会影响排序,以及add()它.


而且,正如@Daniel评论的那样,

通常,Java对象是根据它们提供的功能命名的,而不是根据它们的实现方式命名.


roo*_*ler 6

来自Java 文档

优先级队列表示为平衡二叉堆:queue[n] 的两个子级是queue[2*n+1] 和queue[2*(n+1)]。优先级队列按比较器或元素的自然顺序排序


这是maxHeapminHeap的工作代码,使用PriorityQueue-

class HeapDemo {
    private final static int HEAP_SIZE = 10; //size of heap

    //INNER CLASS
    static class maxHeapComparator implements Comparator<Integer> {
        @Override
        public int compare (Integer x, Integer y) {
            return y-x; //reverse order
        }
    }

    public static void main(String[] args) {
        PriorityQueue<Integer> minHeap = new PriorityQueue<>(HeapDemo.HEAP_SIZE); 
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(HeapDemo.HEAP_SIZE, new maxHeapComparator());  

        for(int i=1; i<=HeapDemo.HEAP_SIZE; ++i){
            int data = new Random().nextInt(100) +1; //number between 0 to 100
            minHeap.add(data);
            maxHeap.add(data);
        }

        System.out.print("\nMIN Heap : ");
        Iterator<Integer> iter = minHeap.iterator();
        while(iter.hasNext()){
            System.out.print(iter.next() + " ");
        }

        System.out.print("\nMAX Heap : ");
        iter = maxHeap.iterator();
        while(iter.hasNext()) {
            System.out.print(iter.next() + " ");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

样本操作:

MIN Heap : 20 32 37 41 53 91 41 98 47 86 
MAX Heap : 98 91 41 53 86 20 37 41 32 47 
Run Code Online (Sandbox Code Playgroud)