当在java中的remove
对象上调用PriorityQueue
方法时,将删除堆的头部。要将新的最小元素放在头部,是否在堆的其余部分完成了任何排序操作?例如,调用compareTo
时调用的remove
方法是什么?
道歉,如果这是在文档中,我无法在任何地方找到它。提前谢谢。
答案 0 :(得分:4)
PriorityQueue
实现为作为数组实现的平衡二进制堆。删除元素时,堆必须重新排序以保持堆的顺序。
证据在评论中
/**
* Priority queue represented as a balanced binary heap: the two
* children of queue[n] are queue[2*n+1] and queue[2*(n+1)]. The
* priority queue is ordered by comparator, or by the elements'
* natural ordering, if comparator is null: For each node n in the
* heap and each descendant d of n, n <= d. The element with the
* lowest value is in queue[0], assuming the queue is nonempty.
*/
private transient Object[] queue;
同样在班级javadoc
中实施说明:此实施提供 O(log(n))时间 enqueing和dequeing方法(offer,poll,remove()和add); remove(Object)和contains(Object)方法的线性时间;和 检索方法的持续时间(窥视,元素和大小)。
例如,对于remove()
,您将删除堆的根。你拿最后一个元素,即。在二叉树的最后一层最右边的叶子,并将其作为根并将其向下筛选直到找到它的位置(基于Comparator
)。这需要花费O(log n)
时间。
答案 1 :(得分:1)
这取决于。如果你remove
数组中支持PriorityQueue
的最后一个元素,则不会进行任何求助。如果您remove
任何其他元素,它会重新排序其元素(siftUp
和siftDown
):
public boolean remove(Object o) {
int i = indexOf(o);
if (i == -1)
return false;
else {
removeAt(i);
return true;
}
}
private E removeAt(int i) {
assert i >= 0 && i < size;
modCount++;
int s = --size;
if (s == i) // removed last element
queue[i] = null;
else {
E moved = (E) queue[s];
queue[s] = null;
siftDown(i, moved);
if (queue[i] == moved) {
siftUp(i, moved);
if (queue[i] != moved)
return moved;
}
}
return null;
}