java中的排序优先级队列

lfapxunr  于 2021-07-12  发布在  Java
关注(0)|答案(5)|浏览(309)

这个问题在这里已经有答案了

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);

}

有人能解释一下为什么吗?
r8uurelv

r8uurelv1#

priorityqueue就是所谓的二进制堆。它只在第一个元素最少的意义上被排序。换句话说,它只关心队列前面的内容,其余的在需要时“排序”。
元素仅在其出列时排序,即使用从队列中移除 poll() . 这就是priorityqueue之所以能够获得如此好的性能的原因,因为它在任何时候都不会进行超出需要的排序。
如果你想详细了解堆是如何工作的,我推荐麻省理工学院关于堆的讲座。

wko9yo5t

wko9yo5t2#

当你打电话的时候 System.out.print() 在你的 PriorityQueue ,它不会 poll() 你的元素,但是 toString() . PriorityQueue 无法实现 toString() ,所以是 toString()AbstractCollection 这将被称为:

public String toString() {
    Iterator<E> i = iterator();
if (! i.hasNext())
    return "[]";

StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
    E e = i.next();
    sb.append(e == this ? "(this Collection)" : e);
    if (! i.hasNext())
    return sb.append(']').toString();
    sb.append(", ");
}
}

如您所见,此方法仅迭代 PriorityQueue . 正如你在照片中看到的 PriorityQueue javadoc公司:
方法iterator()中提供的迭代器不能保证以任何特定顺序遍历优先级队列的元素。如果需要有序遍历,请考虑使用arrays.sort(pq.toarray())。
如果你想使用 PriorityQueue 因为它的意图是使用,你必须 poll() 每个值并打印:

while (!q.isEmpty()) {
    Integer i = q.poll();
    System.out.println(i);
}

输出:

2
4
6
8
xcitsw88

xcitsw883#

那是因为 java.util.PriorityQueue 实现二进制堆。
不幸的是,没有简单的方法来排序priorityqueue。如果你 poll() 对象直到队列为空,元素将按比较器的顺序排列。这就是为什么当我遇到类似的问题时,我实现了自己的heap类,它允许我事后对元素进行排序;我用它来表示大量元素的前n个列表。
(因为我在工作中创建了这个类,所以我无权在这里发布它,但它在很大程度上是模仿python的 heap.py ,所以有很好的灵感来源)

v09wglhw

v09wglhw4#

无界优先级队列基于
priority heap Priority Queue.Offer() 方法使用 siftUpComparable() 在没有比较器的情况下通过时在内部插入项目 siftUpComparable 将当前元素与父位置上的所有元素进行比较( int i = paramInt - 1 >>> 1; )直到满足堆条件 siftUpComparable 简而言之,算法(如果通过数组根=索引0实现):

1.Add the element to the bottom level of the heap.
2.Compare the added element with its parent; if they are in the correct order, stop.
3.If not, swap the element with its parent and return to the previous step.

java代码

private void siftUpComparable(int paramInt, E paramE)
  {
    Comparable localComparable = (Comparable)paramE;
    while (paramInt > 0)
    {
      int i = paramInt - 1 >>> 1;
      Object localObject = this.queue[i];
      if (localComparable.compareTo(localObject) >= 0) {
        break;
      }
      this.queue[paramInt] = localObject;
      paramInt = i;
    }
    this.queue[paramInt] = localComparable;
  }

在您的示例中: q.offer(4); ->插入4
Result: 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]

pkmbmrz7

pkmbmrz75#

java优先级队列应该如何工作?
基本上,print语句不会按顺序遍历树。

相关问题