元素的优先级队列排序

时间:2015-05-06 08:59:46

标签: java scjp

为什么优先队列的元素默认按照自然顺序排序,因为它没有实现类似的接口。

docs开始,它表示元素是根据自然顺序排序的,但我无法在任何地方找到有关equals方法的说法,也无法比较。它内部发生了什么?

  

所有已实现的接口:Serializable,Iterable,Collection,Queue。

如果它具有可比性,那么为什么它没有在上面的行中说明

示例:

    public static void main(String[] args) {
        PriorityQueue<String> pq = new PriorityQueue<String>();
        pq.add("2");
        pq.add("4");
        System.out.println(pq); //prints [2, 4]
        pq.offer("1");
        System.out.println(pq); // prints [1, 4, 2]
        pq.add("3");
        System.out.println(pq); // prints [1, 3, 2, 4]
    }
}

另外,第三个打印语句打印[1,3,2,4]而不是打印[1,2,3,4]。为什么?它应该是自然的顺序吗?

4 个答案:

答案 0 :(得分:6)

实际上PriorityQueue的内部数据结构没有排序,它是 heap

PriorityQueue不需要订购,而是专注于数据。插入位于 O(log n)时间。排序会浪费时间,对队列来说无用。

此外,元素是-a ComparableComparator。不幸的是,不可比较的检查是在运行时,而不是编译时。添加第二个元素后,会发生ClassCastException

加:我回答为什么[1,3,2,4]而不是打印[1,2,3,4]

正如我之前提到的,它没有被订购,相反它专注于头部q[0]是最小的,那就是它。 你可以看到[1,3,2,4]是一个非线性的树:

1
| \
3  2
|
4

答案 1 :(得分:1)

优先级队列依赖于以下内容对元素进行排序:

  • 元素必须是可比较类型
  • 需要为队列提供比较器实现

答案 2 :(得分:0)

实际上,PriorityQueue只允许那些实现Comparable的元素,或者你需要提供Custom Comparator。

Comparator中允许使用Integer和String值,因为它们实现了Comparable接口。例如 public final class String实现java.io.Serializable,Comparable,CharSequence

public final class Integer extends Number实现Comparable

如果您创建自己的类,例如Employee,那么它应该实现Comparable,或者您应该提供自定义Comparator。

我希望这会解决您的疑问!!!!

答案 3 :(得分:0)

您看到的是该订单,因为:

1.内部System.out.println()将调用toString()方法,该方法又使用迭代器迭代队列的元素。但是迭代器不保证任何特定的顺序来遍历元素。请参阅此

http://docs.oracle.com/javase/6/docs/api/java/util/PriorityQueue.html


2。优先级队列基于优先级堆。在没有任何比较器的情况下插入元素时,优先级队列在内部使用siftUpComparable()方法。 siftUpComparable()将当前元素与其在堆中的父位置的元素进行比较。如果订单不正确,则交换当前元素和父元素。这样做直到当前元素和父元素的顺序正确。订购基于元素的自然顺序。

3。由于优先级队列基于优先级堆,因此它的主要焦点将放在队列前面的元素上。 因此,当元素使用poll()从队列中出队时,元素会被排序。这样做是为了提高优先级队列的性能。优先级队列仅在需要时对元素进行排序 如果您想将订单视为[1,2,3,4],请使用此

while(pq.size() != 0) { 
    System.out.println(pq.poll());
}