Java 优先级队列的内部排序

Java 优先级队列的内部排序,java,collections,priority-queue,Java,Collections,Priority Queue,我无法理解在以下情况下发生的内部排序: 这种分类是在什么基础上进行的 说: 这个类及其迭代器实现了 集合和迭代器接口。中提供的迭代器 方法迭代器()不能保证遍历 按任何特定顺序排列的优先级队列。如果需要有序遍历, 考虑使用数组。排序(pq.toAlayle())。 如果你执行 while (!q.isEmpty()) { System.out.println(q.poll()); } 您将看到元素的排序确实正确。APriorityQueue按优先级维护事物。您提取的第一个元素是最高优先

我无法理解在以下情况下发生的内部排序:

这种分类是在什么基础上进行的

说:

这个类及其迭代器实现了 集合和迭代器接口。中提供的迭代器 方法迭代器()不能保证遍历 按任何特定顺序排列的优先级队列。如果需要有序遍历, 考虑使用数组。排序(pq.toAlayle())。

如果你执行

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

您将看到元素的排序确实正确。

A
PriorityQueue
按优先级维护事物。您提取的第一个元素是最高优先级。可能的情况是,这是在下面使用一个以顺序提供数据但不进行完全排序的方法实现的(这允许比每次重新调用内容更有效的插入和删除)


作为消费者,对于优先级队列,内部顺序对您来说并不重要。您应该从中获取元素,并确信它们是最高优先级的。内部构件不是您应该关心的事情(请参阅JB Nizet指出的Java文档)。

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


但是,正如在其他回复中所指出的,Java如何对元素进行内部排序对您来说并不重要,您只希望元素以正确的顺序出现(即优先级较低/较高)。

基本上,它没有排序。优先级队列实现通常分摊排序成本——它们尽可能减少所需的工作量,以确保以正确的顺序检索元素。每次提取一个元素刚好足以选择优先级最高的元素时,它都会进行部分排序。队列从未完全排序


如果您调用
poll()
提取数字,而不是打印整个队列,您将按照预期的顺序重新获取数字

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

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

对于每个节点,子节点存储在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]
列表的排序非常严格,它只在一堆中,当将其打印为列表时,这并不明显。

该特定方法用于对基于优先级的索引进行排序。
 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;
            }
 ```
当remove方法调用时,它将找到优先级最高的索引。 ```java公共删除(){ 如果(索引==0){ System.out.println(“优先级队列为空!!”; 返回null; } int maxIndex=0; //查找具有最高优先级的项的索引 对于(inti=1;i0){ maxIndex=i; } } 可比结果=pQueue[maxIndex]; System.out.println(“删除:+结果”); //将最后一项移到空插槽中 索引--; pQueue[maxIndex]=pQueue[index]; 返回结果; } ```
您可以随时检查JDK的代码,您知道;)简而言之,
整数的自然顺序。我不太同意。。。这是非常排序,它只是在一堆,而不是一个列表。堆维护一个非常特定的排序,如果要删除的下一个元素需要是下一个元素,则允许非常快速的排序。我想知道,这种内部排序是如何发生的。当每个元素都被添加到优先级队列时,某种排序正在进行。那么为什么不看看源代码呢?它是免费提供的,并随JDK提供。谢谢您的回答。此链接:清楚地解释了排序是如何进行的。
[1, 2, 9, 6, 3]
[2, 9, 6, 3]
[3, 9, 6]
[6, 9]
[6]
 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;
            }
 ```