PriorityQueue的内部排序

发布于 2024-12-26 12:36:01 字数 841 浏览 3 评论 0原文

我无法理解 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]

这种排序是在什么基础上进行的?

I'm not able to understand the internal sorting that is taking place in 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("");
    }
}

Output:

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

On what basis is this sorting taking place?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

ぃ弥猫深巷。 2025-01-02 12:36:01

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

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

对于每个节点,子节点存储在 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]

列表已排序,它仅位于堆中,当将其打印为列表时,这一点并不明显。

The priority queue is implemented as a heap, where all children for a specific node is of lower priority than it's parent, but not necessarily of it's siblings.

The elements are stored in the array (I suspect) as follows:

For each node, the children are stored in 2*pos and 2*pos+1. Thus, for [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...

If you remove from the queue the parent node is replaced by one of the children with the highest priority, which again is replaced by one of its children, etc. (The operation is very optimal, only O(log n) running time) For example:

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

The list is very much sorted, it's only in a heap which is not that evident when printing it our as a list.

我早已燃尽 2025-01-02 12:36:01

javadoc 说:

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

如果执行,

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

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

The javadoc says:

This class and its iterator implement all of the optional methods of
the Collection and Iterator interfaces. The Iterator provided in
method iterator() is not guaranteed to traverse the elements of the
priority queue in any particular order. If you need ordered traversal,
consider using Arrays.sort(pq.toArray()).

If you execute

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

You'll see that the elements are indeed sorted correctly.

把时间冻结 2025-01-02 12:36:01

PriorityQueue 按优先级顺序维护事物。您取出的第一个元素具有最高优先级。这很可能是使用 堆数据结构 实现的,它按顺序提供数据,但无需完全排序(这比每次重新排列内容可以更有效地插入和删除)。

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

A PriorityQueue maintains things in order of priority. The first element you pull out is the highest priority. The likelhood is that this is implemented underneath using a heap data structure which provides the data in an order but without the full sorting (this allows more efficient insertion and deletion than resorting the contents each time).

As a consumer, the internal order is not important to you for a priority queue. You should just grab elements from it and be satisfied that they are the highest priority. The internals aren't something you should concern yourself with (see the Java doc that JB Nizet pointed out).

忆悲凉 2025-01-02 12:36:01

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

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

I haven't done anything in Java for the past 7 years, but most probably the ordering is some kind of heap.

However, as noted in other replies, how Java orders the elements internally shouldn't matter to you, you just want the elements to come out in the right order (i.e. lower/higher priority first).

2025-01-02 12:36:01

基本上,它没有排序。优先级队列实现通常会摊销排序成本 - 它们会花费最少的精力来确保以正确的顺序检索元素。每次提取一个元素足以选择最高优先级元素时,它都会进行部分排序。队列永远不会完全排序。

如果您调用 poll() 来提取数字,而不是打印整个队列,您将按照您期望的顺序获取它们。

Basically, it's not sorted. Priority queue implementations usually amortize the sorting cost - they do the minimum amount of effort needed to ensure that elements are retrieved in the right order. It's partially sorted each time an element is extracted just enough to choose the highest priority element. The queue is never fully sorted.

Instead of printing the whole queue, if you call poll() to extract the numbers, you'll get them back in the order you expect.

萌化 2025-01-02 12:36:01
 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;
            }
 ```
 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;
            }
 ```
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文