我是算法分析和SML的新手,並且掛上了以下SML函數的平均情況運行時。我會很感激我的想法。瞭解涉及列表追加的遞歸SML函數的運行時(使用@)
fun app([]) = []
| app(h::t) = [h] @ app(t)
所以在每次遞歸之後,我們最終會得到一堆單個元素列表(和一個無元素列表)。
[1]@[2]@[3]@[email protected][n]@[]
凡n
是在原列表和元素1, 2, 3, ..., n
的數量只是爲了說明我們正在談論在原始列表中哪些元素。 L @ R
需要時間線性列表L.假設A
的長度是@需要爲每個元素的時間相同的量,我想這彷彿:
[1,2]@[3]@[4]@[email protected][n]@[] took 1A
[1,2,3]@[4]@[email protected][n]@[] took 2A
[1,2,3,4]@[email protected][n]@[] took 3A
...
[1,2,3,4,...,n]@[] took (n-1)A
[1,2,3,4,...,n] took nA
我因此想,對於時間會復發是這個樣子:
T(0) = C (if n = 0)
T(n) = T(n-1) + An + B (if n > 0)
哪裏C
只是基本情況app([])
和B
的最終匹配是h::t
常數。關閉復發,我們會得到這個(證明從略):
T(n) = (n²+n)A/2 + Bn + C = (A/2)n² + (A/2)n + Bn + C = Θ(n²)
這是我自己的結論,從已提交給我答案,即不同:
T(0) = B (if n = 0)
T(n) = T(n-1) + A (if n > 0)
封閉形式
T(n) = An + B = Θ(n)
這是完全不同的。 (Θ(n)vsΘ(n²)!)但是,這不是假設L @ R
需要恆定的時間而不是線性?例如,這將是另外
fun add([]) = 0
| add(h::t) = h + add(t) (* n + ... + 2 + 1 + 0 *)
甚至串聯
fun con([]) = []
| con(h::t) = h::con(t) (* n :: ... :: 2 :: 1 :: [] *)
我誤解是L @ R
存在,或者是我的分析(至少在某種程度上)正確的方式真的嗎?
'@'是左操作數列表的大小呈線性關係,但在這裏,它總是被稱爲一個元素列表上。 –
我想我明白了。我按照相反順序添加列表,即[1] @ [2] @ [3] @ [4] @ ... @ [n] @ []最終會是[1] @ [2,3, ...,N]。這是正確的嗎? – Max
是的,沒錯。你所執行的每個追加都是恆定的。 –