簡體   English   中英

此方法是O(log N)還是恆定時間?

[英]Is this method O(log N) or constant time?

我有一個將元素插入優先級隊列的方法。 我想知道它的演奏時間

我相信如果要插入的元素可以放在隊列的底部,則可能是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;
}

在回答您的問題“這個推理正確嗎?”時,我會說“否”。 通常, O()表示法表示算法最壞情況下的復雜性。 有時,它可以用於平均情況下的復雜性,但很少用於最佳情況下的復雜性。 (見這里當你可能會使用它的例子。)你認為該算法是O(1)在最好的情況的情況下,但並不表明它是O(1)平均或最壞情況下的情況。

enlargeArray()考慮對enlargeArray()函數的復雜性的enlargeArray()盡管它的攤銷時間不是O(log N) ,它可能比O(log N)還要復雜,但另一方面,它實際上並不是“適當的算法”的一部分,因為您總是可以將數組預先分配為“足夠大”),我想說您的插入算法為O(log N)因為這既是平均復雜度,也是最壞情況下的復雜度。

Luiggi和mkrakhin都是正確的:如果您需要擴大數組,則expandArray調用可以為O(n) ,但是由於您使數組的大小不斷加倍,從長遠來看,它只會發生對數次,因此整個事情將攤銷為O(log N)。

但是,我認為您要問的真正問題是,如果新元素最小,此算法是否為O(1),答案是“是的,只要您不需要調用expandArray”即可。 看到這種情況的方法是注意到您將完全通過for循環0次,因此唯一的“完成的工作”將是:

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

注意:在這種情況下,我認為這似乎也表明存在錯誤(我想在要交換時,將相同的元素放在數組的開頭和結尾)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM