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

时间:2011-05-19 22:51:06

标签: java priority-queue

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

6 个答案:

答案 0 :(得分:66)

默认的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;
    }
}

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

PriorityQueue minHeap=new PriorityQueue();
PriorityQueue maxHeap=new PriorityQueue(size, new MyComparator());

答案 1 :(得分:37)

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

PriorityQueue<Integer> queue = new PriorityQueue<>(10, Collections.reverseOrder());

答案 2 :(得分:19)

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

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

PriorityQueue(int, java.util.Comparator)

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

比较器给出的顺序将代表队列中的优先级。

答案 3 :(得分:6)

来自the PriorityQueue JavaDocs

  

基于优先级堆的无界优先级队列。优先级队列的元素按照其自然顺序排序,或者在队列构造时提供Comparator,具体取决于使用的构造函数。

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


并且,正如@Daniel所评论的那样,

  

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

答案 4 :(得分:2)

来自Java docs

  

优先级队列表示为平衡二进制堆:queue [n]的两个子节点是队列[2 * n + 1]和队列[2 *(n + 1)]。优先级队列由比较器排序,或由元素&#39; 自然排序

以下是使用PriorityQueue maxHeap minHeap 的工作代码 -

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() + " ");
        }
    }
}

样本o / p:

MIN Heap : 20 32 37 41 53 91 41 98 47 86 
MAX Heap : 98 91 41 53 86 20 37 41 32 47 

答案 5 :(得分:1)

来自http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html

  

基于优先级堆的无界优先级队列。优先级队列的元素按照自然排序或在队列构建时提供的比较器进行排序

对于整数,long,float,double,character,boolean(即原始数据类型)自然排序是升序,这就是为什么Arrays.sort(arr){其中arr是一个数组原始数据类型}按升序对arr的值进行排序。您可以使用比较器

更改自然顺序

比较器可以两种方式使用

Arrays.sort(arr, new Comparator<Integer> {
     public int compare(Integer x, Integer y) {
         return y - x;
     }
 }
  • 如果您有java8,则可以使用lambda表达式

Arrays.sort(arr, (Integer x, Integer y) -> y - x);

这会按降序对数组arr进行排序