这个问题在这里已经有答案了:
java的priorityqueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么(5个答案)
6年前关门了。
我想把整数插入 PriorityQueue
,我知道:
如果没有指定比较器 PriorityQueue
则使用队列中存储的数据类型的默认比较器。默认的比较器将按升序排列队列
但是,我得到的输出不是按顺序排列的。运行以下代码后的输出是: [2, 4, 8, 6]
```
public static void main(String args[]) {
PriorityQueue q = new PriorityQueue(10);
q.offer(4);
q.offer(2);
q.offer(8);
q.offer(6);
System.out.print(q);
}
有人能解释一下为什么吗?
5条答案
按热度按时间r8uurelv1#
priorityqueue就是所谓的二进制堆。它只在第一个元素最少的意义上被排序。换句话说,它只关心队列前面的内容,其余的在需要时“排序”。
元素仅在其出列时排序,即使用从队列中移除
poll()
. 这就是priorityqueue之所以能够获得如此好的性能的原因,因为它在任何时候都不会进行超出需要的排序。如果你想详细了解堆是如何工作的,我推荐麻省理工学院关于堆的讲座。
wko9yo5t2#
当你打电话的时候
System.out.print()
在你的PriorityQueue
,它不会poll()
你的元素,但是toString()
.PriorityQueue
无法实现toString()
,所以是toString()
从AbstractCollection
这将被称为:如您所见,此方法仅迭代
PriorityQueue
. 正如你在照片中看到的PriorityQueue
javadoc公司:方法iterator()中提供的迭代器不能保证以任何特定顺序遍历优先级队列的元素。如果需要有序遍历,请考虑使用arrays.sort(pq.toarray())。
如果你想使用
PriorityQueue
因为它的意图是使用,你必须poll()
每个值并打印:输出:
xcitsw883#
那是因为
java.util.PriorityQueue
实现二进制堆。不幸的是,没有简单的方法来排序priorityqueue。如果你
poll()
对象直到队列为空,元素将按比较器的顺序排列。这就是为什么当我遇到类似的问题时,我实现了自己的heap类,它允许我事后对元素进行排序;我用它来表示大量元素的前n个列表。(因为我在工作中创建了这个类,所以我无权在这里发布它,但它在很大程度上是模仿python的
heap.py
,所以有很好的灵感来源)v09wglhw4#
无界优先级队列基于
priority heap
Priority Queue.Offer()
方法使用siftUpComparable()
在没有比较器的情况下通过时在内部插入项目siftUpComparable
将当前元素与父位置上的所有元素进行比较(int i = paramInt - 1 >>> 1;
)直到满足堆条件siftUpComparable
简而言之,算法(如果通过数组根=索引0实现):java代码
在您的示例中:
q.offer(4);
->插入4Result: PQ[0]=4
q.offer(2);
->siftUpComparable
比较4到2和交换位置(在父位置进行比较)Result: PQ[0]=2,PQ[1]=4
q.offer(8);
->siftUpComparable
比较8和2(因为2在父位置)Result: PQ[2]=8
q.offer(6);
:->siftup比较6和4(根据paramInt - 1 >>> 1;
(逻辑)Result: PQ[3]=6
最终PQ=[2, 4, 8, 6]
pkmbmrz75#
java优先级队列应该如何工作?
基本上,print语句不会按顺序遍历树。