【问题标题】:Order of priorityQueue in Java? [duplicate]Java中priorityQueue的顺序? [复制]
【发布时间】:2013-07-15 07:42:06
【问题描述】:

我无法理解 Java 中 PriorityQueue 的顺序。据我了解,它们是基于堆的,它们不能提供精确的迭代顺序作为插入顺序。我想知道然后根据priorityQueue 对自己进行排序。 给定代码:

PriorityQueue<String> pq = new PriorityQueue<String>();
        pq.offer("hepqo");
        pq.offer("bro");
        pq.offer("wassup");
        pq.offer("okay");
        pq.offer("bingo");
        pq.offer("first");
        pq.offer("last");
        pq.offer("ssup");
        System.out.println("polled "+pq.poll());
        System.out.println(pq);
        String str[] = pq.toArray(new String[0]);
        Arrays.sort(str);
        for(String str1:str){
            System.out.println(str1);
        }

产生输出:

polledbingo
[bro, hepqo, first, okay, ssup, wassup, last]
bro
first
hepqo
last
okay
ssup
wassup

即使我将其转换为数组,订单也会丢失。
我感觉不到这甚至是字符串的自然排序。
有什么办法可以保持优先队列的插入顺序?
他们的排序依据是什么?

【问题讨论】:

  • 其实就是字符串的自然排序。
  • 阅读JavaDocs:“方法iterator()中提供的迭代器保证遍历优先队列的元素以任何特定的顺序。” docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html
  • PriorityQueue 中提供排序的唯一方法是 poll()peek(),您没有使用其中任何一个。在我看来,您想要一个 FIFO 队列,而不是 PriorityQueue
  • 先进先出队列:LinkedListArrayDeque
  • poll()peek() 根据类的 Comparable.compareTo() 实现或您提供的 Comparator 维护排序。这些都在 Javadoc 中。你读过吗?

标签: java collections queue priority-queue


【解决方案1】:

队列根据字符串的字典顺序排序,这是它们的自然顺序(即“b”在“f”之前,“f”在“h”之前,等等)。如果您希望队列保持插入顺序,请使用原版 Queue 而不是 PriorityQueue

【讨论】:

  • 在我的输出中,为什么lastwassup 之后??
  • @Sachin Verma 从toArray 输出的元素没有特定的顺序——只有polliterator 等保证遵守队列的顺序
  • @Zim-ZamO'Pootertoot 否。请参阅 Javadoc:“方法 iterator() 中提供的 Iterator 不保证以任何特定顺序遍历优先级队列的元素。”仅通过peek()poll() 方法提供订购。
  • 你怎么知道这个(“队列是按照字符串的字典顺序排序的,这是它们的自然顺序”)?有官方参考吗?
【解决方案2】:

Java 中的优先级队列是所谓的Heap(这是一种抽象数据结构)的实现。如果您查看堆数据结构,则键(或 Java 术语中的集合元素)之间没有严格的排序原则。堆 ADT 主要用于快速插入/删除和 O(K) 时间检索第一个元素(在堆的情况下将是根)。所以不要使用 Java 中的 PriorityQueue 数据结构来搜索所有元素、排序元素或遍历元素。因为它不是为了这些目的。 javadoc 清楚地指出,Collection 和 Iterable 接口中的 optional 实现不是可以依赖的(即,Iterator 返回一个不保证顺序的实现,并且 Collection 方法(如 remove())包含() 需要线性时间)

【讨论】:

  • 当然有“严格原则”。否则它将无法正常工作。 “严格原则”是A[i] &lt;= A[i*2] &lt;= A[i*2+1]。您当然可以使用它进行排序。 Iterator 方法 hasNext()next() 不是可选的。这里太混乱了。
猜你喜欢
  • 1970-01-01
  • 2015-07-08
  • 2012-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多