PriorityQueue的remove方法是否会重新排列堆?

时间:2013-10-08 02:41:37

标签: java sorting queue compare heap

当在java中的remove对象上调用PriorityQueue方法时,将删除堆的头部。要将新的最小元素放在头部,是否在堆的其余部分完成了任何排序操作?例如,调用compareTo时调用的remove方法是什么?

道歉,如果这是在文档中,我无法在任何地方找到它。提前谢谢。

2 个答案:

答案 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任何其他元素,它会重新排序其元素(siftUpsiftDown):

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;
}