[英]Calculating time complexity of a recursive algorithm
我正在嘗試計算遞歸算法的時間復雜度,我想我已經差不多了。 這是我一直在查看的偽代碼:
long pow( long x, int n ) {
if (n == 0)
return 1;
if (n == 1)
return x;
if(isEven(n))
return pow(x, n / 2 ) * pow(x, n / 2);
else
return x * pow(x * x, n / 2);
}
isEven 僅確定傳遞給它的整數是否為偶數,並且就本示例而言,它在恆定時間內運行。
因此,如果 n = 0 或 n = 1,則它以恆定時間運行,如下所示:f(n) = C0。 然而,當 n > 1 時,它應該像這樣操作: f(n)= f(n-1) + f(n-1) + C1 當 n 是偶數並且 f(n)= f(n-1) + 1 當 n 是奇數時,對嗎? 或者它應該是:當 n 是偶數時 f(n)= f(n/2) + f(n/2) + C1 而當 n 是奇數時 f(n)= f(n/2) + 1?
我一直在看很多例子。 這是我發現非常有幫助的一個。 我的問題源於當 n 為偶數時有兩個遞歸調用。 我不完全確定在這里做什么。 如果有人能指出我正確的方向,我將不勝感激。
看看大師定理。 您可以將其視為“分而治之”算法。
最終結果是,在兩個遞歸調用到位后,您最終會得到最壞的 O(n) 運行時情況。 例如 pow(x, 4) 調用 pow(x, 2) 兩次,pow(x, 1) 調用四次; 通常,2 的冪將導致 n*2-1 調用。
另請注意,只需調用一次 pow(x, n/2) 並將該分支中的結果平方,算法就變成了 O(log n)。
讓我們定義 f(m) ,因為它為您提供大小為 m 的問題的操作數。 “問題”當然是冪運算 (pow),例如x^n
或pow(x,n)
。 如果我更改 x long pow( long x, int n ) {
函數不需要做更多或更少的工作。 因此,問題求冪的大小不依賴於 x。 然而,它確實取決於 n。 假設 2^4 的大小為 4,而 3^120 的大小為 120。(如果您看到2^4=2*2*2*2
和3^120=3*3*3*3*..*3
,這是有道理的3^120=3*3*3*3*..*3
) 問題大小因此等於n
,即第二個參數。 如果您願意,我們可以說問題大小為 2*log(n),但這很愚蠢。
現在我們有 f(m) 是計算任何 x 的pow(x,m)
的操作數。 因為pow(x,m)
正是大小為 m 的問題。 因此,如果我們有pow(x,y)
那么根據定義,操作次數是f(y)
。 例如, pow(3,3*m/2)
有f(3*m/2)
操作。
最后,讓我們計算一下操作
long pow( long x, int n ) {
if (n == 0) //1
return 1;
if (n == 1) //1
return x;
if(isEven(n)) //1
return pow(x, n / 2 ) * //that is f(n/2), y=n / 2
pow(x, n / 2); //also f(n/2)
else
return x * pow(x * x, n / 2); //1+1+f(n/2)
}
綜合考慮: f(n) = 2*f(n/2) + c1
(n 偶數)和f(n) = f(n/2) + c2
(n 奇數)。 如果您只對最壞的情況感興趣,請注意奇數情況的工作量較少。 因此 f(n) 受偶數情況的限制: f(n) <= 2*f(n/2)+c
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.