PriorityQueue的内部排序

时间:2012-01-12 09:19:38

标签: java collections priority-queue

我无法理解PriorityQueue中发生的内部排序:

import java.util.*;

public class TryME {
    public static void main(String args[]) {
        PriorityQueue<Integer> q = new PriorityQueue<Integer>();
        q.add(3);
        System.out.print(q);
        System.out.print("");
        q.add(1);
        System.out.print(q);
        System.out.print("");
        q.add(9);
        System.out.print(q);
        System.out.print("");
        q.add(6);
        System.out.print(q);
        System.out.print("");
        q.add(2);
        System.out.print(q);
        System.out.print("");
    }
}

输出:

[3][1, 3][1, 3, 9][1, 3, 9, 6][1, 2, 9, 6, 3]

这种分类的基础是什么?

6 个答案:

答案 0 :(得分:2)

The javadoc说:

  

这个类及其迭代器实现了所有可选方法   Collection和Iterator接口。迭代器提供   方法iterator()不保证遍历元素   任何特定顺序的优先级队列。如果您需要有序遍历,   考虑使用Arrays.sort(pq.toArray())。

如果你执行

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

您会看到元素确实正确排序。

答案 1 :(得分:2)

优先级队列实现为堆,其中特定节点的所有子节点的优先级低于其父节点,但不一定是它的兄弟节点。

元素存储在数组中(我怀疑)如下:

对于每个节点,子节点存储在2 * pos和2 * pos + 1中。因此,对于[1,2,9,6,3]:

element 1 (value 1), children are 2 and 9.
element 2 (value 2), children are 6 and 3
element 3 (value 9), 4 (value 6) and 5 (value 3) have no children...

如果从队列中删除,父节点将被其中一个具有最高优先级的子节点替换,该子节点将被其子节点之一替换为等等(操作非常优化,只有O(log n)正在运行时间)例如:

[1, 2, 9, 6, 3]
[2, 9, 6, 3]
[3, 9, 6]
[6, 9]
[6]

列表非常有条理,它只在一个堆中,当我们将它们打印为列表时,这个堆就不那么明显了。

答案 2 :(得分:1)

PriorityQueue按优先顺序维护事物。您提取的第一个元素是最高优先级。可能的情况是,这是使用heap data structure在下面实现的,{{3}}提供订单中的数据,但没有完整的排序(这允许更有效的插入和删除,而不是每次都使用内容)。

作为消费者,内部订单对于优先级队列并不重要。您应该从中获取元素并确信它们是最高优先级。内部结构不是你应该关心的东西(参见JB Nizet指出的Java文档)。

答案 3 :(得分:0)

在过去的7年里,我没有用Java做任何事情,但很可能排序是某种heap

然而,正如其他回复中所述,Java如何在内部对元素进行排序对您来说无关紧要,您只需要按正确的顺序排列元素(即首先是较低/较高优先级)。

答案 4 :(得分:0)

基本上,它没有排序。优先级队列实现通常分摊排序成本 - 它们执行所需的最少工作量以确保以正确的顺序检索元素。每次提取元素时,它都会被部分排序,以便选择最高优先级的元素。队列永远不会完全排序。

如果您拨打poll()来提取数字,而不是打印整个队列,您将按照预期的顺序将其恢复。

答案 5 :(得分:0)

 That particular method is used to sort the priority based index.
 When that remove method will call it will find the highest priority index.
       ```java  public Comparable remove(){
                if(index == 0){
                    System.out.println("The priority queue is empty!!");
                    return null;
                }
                int maxIndex = 0;
                // find the index of the item with the highest priority 
                for (int i=1; i<index; i++) { 
                    if (pQueue[i].compareTo (pQueue[maxIndex]) > 0) { 
                        maxIndex = i; 
                    } 
                } 
                Comparable result = pQueue[maxIndex]; 
                System.out.println("removing: "+result);
                // move the last item into the empty slot 
                index--; 
                pQueue[maxIndex] = pQueue[index]; 
                return result;
            }
 ```