1

Java Doc 说:创建一个具有默认初始容量 (11) 的 PriorityQueue,它根据元素的自然顺序对其元素进行排序。

但是当我写一些这样的测试时:

public class Test {

    public static void main (String a[]) {
        Queue<Integer> queue = new PriorityQueue<Integer>();

        for (int i = 1; i <= 20; i++) {
            queue.offer(i);
        }

        System.out.println(queue);

        Queue<Integer> queue2 = new PriorityQueue<Integer>();

        for (int i = 20; i >= 1; i--) {
            queue2.offer(i);
        }

        System.out.println(queue2);
    }
}

我得到以下输出:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[1, 2, 7, 4, 3, 10, 8, 11, 5, 12, 13, 19, 15, 16, 9, 20, 14, 17, 6, 18]

看起来像两个具有相同内容的队列,它们的内容没有得到相同的顺序?

4

2 回答 2

6

优先级队列不保证完整集合的顺序;它只保证最小的元素在前面(或者最大的,如果它是一个最大优先级队列)。

从文档:

方法 iterator() 中提供的 Iterator 不能保证以任何特定顺序遍历优先级队列的元素。如果您需要有序遍历,请考虑使用 Arrays.sort(pq.toArray())。

也许要添加一点上下文:优先级队列在内部所做的是将元素存储在对数高度的树结构中(无论如何在使用树的合理实现中)。和insertremove-like 操作旨在将最小元素保留在该树的根部,并使每个子树中的元素大于父顶点的元素(这就是使它们成为堆的原因,该属性称为堆属性) . 它不保证对作为兄弟的子树的元素进行任何排序,例如我们从排序树中所知道的。堆属性与对数高度一起为优先级队列提供了快速操作运行时间,但它的缺点是您只能快速获得一个元素,这是最小的一个(或最大堆最大的一个)。

于 2013-11-06T01:13:24.143 回答
0

PriorityQueue.toString 使用 iterator()不能保证以任何特定顺序 (来自 API)遍历优先级队列的元素。尝试

    while(!queue.isEmpty()) {
            System.out.print(queue.poll() + ",");
    }
于 2013-11-06T02:58:00.883 回答