简体   繁体   English

将值添加到优先级队列时,何时对值进行准确排序?

[英]When adding values to a priority queue, when exactly are the values sorted?

Consider this pseudo-code: 考虑以下伪代码:

PriorityQueue <Integer> pq = new PriorityQueue(new Comparator()
{
    public int compare(Object o1, Object o2) 
    {
         Integer e1 = (Integer)o1;
         Integer e2 = (Integer)o2;
         if (e1 > e2) {return -1;}
         if (e2 > e1) {return 1;}
         return 0;
     }
});

pq.add(4);
pq.add(7);
pq.add(5);
pq.add(2);
pq.add(9);

Now I'm wondering, when exactly during the run time does the queue run the compare() method? 现在,我想知道队列何时恰好在运行时运行compare()方法? I assumed that it would follow this order: 我假设它将遵循以下顺序:

i) First the numbers 4,7,5,2,9 are added to the queue in that order i)首先将数字4,7,5,2,9依次添加到队列中

ii) Then the priority queue uses the compare method to sort the values ii)然后优先级队列使用compare方法对值进行排序

In other words, the values are first inserted into the queue. 换句话说,首先将值插入队列。 Then they are sorted. 然后将它们排序。 Is this thinking correct? 这种想法正确吗? Or are the values sorted as they're being added to the queue? 还是在将值添加到队列时对它们进行排序?

PriorityQueues are not a simple sorted data structures like kind of sorted array. PriorityQueue不是像排序数组那样的简单排序数据结构。 PriorityQueue in java was implemented using priority heaps. Java中的PriorityQueue是使用优先级堆实现的。 You should learn how heaps work, but basically when you add a new element, maximum log(n) comparisons occurs. 您应该了解堆的工作方式,但是基本上,当您添加新元素时,将进行最大log(n)比较。 Comparing all elements with each other is not necessary. 不需要将所有元素相互比较。 You can learn more about priority queues at https://en.m.wikipedia.org/wiki/Priority_queue 您可以在https://en.m.wikipedia.org/wiki/Priority_queue上了解有关优先级队列的更多信息。

PriorityQueue class has a private field Comparator defined for the insertion order ( private final Comparator<? super E> comparator )... so when you do: PriorityQueue类具有为插入顺序定义的私有字段Comparatorprivate final Comparator<? super E> comparator )...因此,当您执行以下操作时:

PriorityQueue<Integer> pq = new PriorityQueue<>(foo);

where foo is an instance of the comparator, that object will be initialized internally for that instance... 其中foo是比较器的实例,该对象将在内部为该实例初始化...

after the collection is created, you begin to add elements to it and here is where the magic happens. 创建集合后,您便开始向其中添加元素,这就是魔术发生的地方。

just look inside the PriorityQueue class and you will find the method siftUpUsingComparator , that will be invoked, and uses the comparator you defined to verify the insertion order... 只需查看PriorityQueue类内部,您将找到siftUpUsingComparator方法,该方法将被调用,并使用您定义的比较器来验证插入顺序...

private void siftUpUsingComparator(int k, E x) {
    while (k > 0) {
        int parent = (k - 1) >>> 1;
        Object e = queue[parent];
        if (comparator.compare(x, (E) e) >= 0)
            break;
        queue[k] = e;
        k = parent;
    }
    queue[k] = x;
}

Offtopic: 无关:

you are using raw collections and that is bad, I sugest to adapt your code to something like: 您正在使用原始集合,那很不好,我很高兴地将您的代码调整为类似以下内容:

Comparator<Integer> foo = (o1, o2) -> {
    Integer e1 = o1;
    Integer e2 = o2;
    if (e1 > e2) {
        return -1;
    }
    if (e2 > e1) {
        return 1;
    }
    return 0;
};
PriorityQueue<Integer> pq = new PriorityQueue<>(foo);

pq.add(4);
pq.add(7);
pq.add(5);
pq.add(2);
pq.add(9);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM