这个方法是O(log N)还是恒定时间?

时间:2014-03-06 06:34:56

标签: java queue complexity-theory time-complexity priority-queue

我有一个将元素插入优先级队列的方法。我想知道它有性能时间

我相信如果插入的元素可以放在队列的底部,它可以是O(1)。但是,如果要插入的元素是新的最小值并且一直渗透到根目录,它将在O(log N)时间运行。 这种推理是否正确?

以下是方法插入方法:

/**
 * Insert into the priority queue, maintaining heap order.
 * Duplicates are allowed.
 * @param x the item to insert.
 */
public void insert( AnyType x )
{
    if( currentSize == array.length - 1 )
        enlargeArray( array.length * 2 + 1 );

        // Percolate up
    int hole = ++currentSize;
    for( array[ 0 ] = x; x.compareTo( array[ hole / 2 ] ) < 0; hole /= 2 )
        array[ hole ] = array[ hole / 2 ];
    array[ hole ] = x;
}

2 个答案:

答案 0 :(得分:0)

我会说“不”回答你的问题“这个推理是否正确?”通常,O()表示法被视为算法的最坏情况复杂度的指示。有时它可用于平均情况复杂性,但很少用于最佳情况复杂性。 (有关您可以使用它的示例,请参阅here。)您认为在最佳情况下算法为O(1),但并非平均或最差O(1) - 情况。

暂且不关心enlargeArray()函数的复杂性(虽然它的摊销时间不是,但这可能会超过O(log N),但另一方面却不是“{1}}的一部分。”算法正确“无论如何,因为你总是可以预先分配数组”足够大“),我会说你的插入算法是O(log N),因为这是平均和最差情况的复杂性。

答案 1 :(得分:0)

Luiggi和mkrakhin都是正确的:如果你需要放大数组,那么的enlargeArray调用可以是O(n),但是既然你要保持数组的大小加倍,那么从长远来看它只会发生对数所以整个事情将分摊为O(log N)的次数。

但是,我认为你问的真正问题是,如果新元素是最小的,那么这个算法是O(1),答案是“是,只要你不需要调用enlargeArray” 。看到这种方式的方法是注意你将完全通过你的for循环0次,所以唯一的“完成的工作”将是:

int hole = ++currentSize;
array[0] = x;
array[hole] = x;

注意:我认为这似乎也表明了这种情况下的错误(你想在交换时把相同的元素放在数组的开头和结尾)。