考虑这个伪代码:
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);
现在我想知道,在运行时是否恰好在队列中运行compare()方法?我以为它会遵循这个顺序:
i)首先,数字4,7,5,2,9按顺序添加到队列中
ii)然后优先级队列使用compare方法对值进行排序
换句话说,首先将值插入队列中。然后他们排序。这个想法是否正确?或者在将值添加到队列中时对值进行排序?
答案 0 :(得分:1)
PriorityQueues不是一种简单的排序数据结构,就像排序数组一样。 java中的PriorityQueue是使用优先级堆实现的。您应该了解堆的工作原理,但基本上在添加新元素时,会发生最大的log(n)比较。不必将所有元素相互比较。您可以在https://en.m.wikipedia.org/wiki/Priority_queue
了解有关优先级排队的详情答案 1 :(得分:1)
PriorityQueue
类为插入顺序(Comparator
)定义了一个私有字段private final Comparator<? super E> comparator
...所以当你这样做时:
PriorityQueue<Integer> pq = new PriorityQueue<>(foo);
其中foo是比较器的一个实例,该对象将在内部为该实例初始化...
创建集合后,您开始向其添加元素,这就是魔术发生的地方。
只需查看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:
你正在使用原始集合,这很糟糕,我觉得你的代码适应:
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);