Java 此方法是O(对数N)还是恒定时间?

Java 此方法是O(对数N)还是恒定时间?,java,queue,complexity-theory,time-complexity,priority-queue,Java,Queue,Complexity Theory,Time Complexity,Priority Queue,我有一个将元素插入优先级队列的方法。我想知道它的表演时间 如果插入的元素可以放在队列的底部,我相信它可以是O(1)。但是,如果要插入的元素是新的最小值并且一直渗透到根,则它将在O(logn)时间运行这个推理正确吗? 以下是方法插入方法: /** * Insert into the priority queue, maintaining heap order. * Duplicates are allowed. * @param x the item to insert. */ publi

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

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

以下是方法插入方法:

/**
 * 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;
}
/**
*插入优先级队列,保持堆顺序。
*允许重复。
*@param x要插入的项目。
*/
公共无效插入(任意类型x)
{
if(currentSize==array.length-1)
放大阵列(array.length*2+1);
//渗透
int-hole=++currentSize;
对于(数组[0]=x;x.compareTo(数组[hole/2])<0;hole/=2)
数组[孔]=数组[孔/2];
数组[孔]=x;
}
在回答您的问题“这个推理正确吗?”时,我会说“不”。通常,
O()
符号表示算法的最坏情况复杂性。有时,它可以用于平均案例复杂度,但很少用于最佳案例复杂度。(请参见您可能使用它的示例。)您认为该算法在最佳情况下是
O(1)
,但在平均或最坏情况下不是
O(1)


撇开对
enlargeArray()
函数复杂性的担忧不谈(这很可能会使它比
O(logn)
更复杂,尽管它的摊销时间不是,但另一方面,它并不是真正的“算法正确”的一部分,因为你总是可以将数组预分配为“足够大”),我认为您的插入算法是
O(logn)
,因为这是平均和最坏情况下的复杂度

Luiggi和mkrakhin都是正确的:如果需要放大数组,EnglargerArray调用可以是
O(n)
,但由于数组的大小一直是原来的两倍,因此从长远来看,它只会发生对数次,所以整个过程将摊销为O(logn)

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

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

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

时间将是O(n),因为
enlargeArray
是O(n)。@LuiggiMendoza,是的,但只有在最坏的情况下。摊销时间为O(对数N)。@mkrakhin是的,但OP没有要求摊销时间。