filter
有n
遞歸調用,但是你也在每次迭代時做一個複製操作,這需要n
,所以你最終得到Θ(n^2)。如果你實現了'正確'它應該是Θ(n)。
與my_reverse
相同。
與revfilter_beta
相同。
revfilter_alpha
只是做了一個filter
然後一個reverse
,使得Θ(n^2 + n^2)=Θ(n^2)。
編輯:讓我們來看看filter
多一點。
你想知道的是相對於輸入大小執行了多少操作。 O(n)
表示在最壞的情況下,您將按照n
的操作順序進行操作。我說「按順序」,因爲你可以,例如,做O(n/2)
操作,或O(4n)
,但最重要的因素是n
。也就是說,隨着n
增長,常數因子變得越來越不重要,所以我們只查看非常數因子(在這種情況下爲n
)。
那麼,filter
在n
的大小列表上執行多少操作?
讓我們從下往上看。 n
是0還是空列表?然後它會返回一個空列表。所以我們說這是1個操作。
如果n
是1呢?它將檢查是否應該包含lst[0]
--該檢查需要很長時間才能調用f
- 然後它將複製列表的其餘部分,並對該副本執行遞歸調用,在這種情況下,這是一個空列表。所以filter(1)
需要f + copy(0) + filter(0)
操作,其中copy(n)
是複製列表需要多長時間,並且f
是檢查是否應該包含元素需要多長時間,假定每個元素需要相同的時間量。
filter(2)
怎麼樣?它將執行1次檢查,然後複製剩餘的清單,並在餘下部分撥打filter
:f + copy(1) + filter(1)
。
您可以看到圖案。filter(n)
需要1 + copy(n-1) + filter(n-1)
。現在
,copy(n)
只是n
- 它需要n
操作切片以這種方式列表。所以我們可以進一步簡化:filter(n) = f + n-1 + filter(n-1)
。
現在,你可以嘗試只擴大了filter(n-1)
幾次,看看會發生什麼:
filter(n) = f + n-1 + filter(n-1)
= 1 + n-1 + (f + n-2 + filter(n-2))
= f + n-1 + f + n-2 + filter(n-2)
= 2f + 2n-3 + filter(n-2)
= 2f + 2n-3 + (f + n-3 + filter(n-3))
= 3f + 3n-6 + filter(n-3)
= 3f + 3n-6 + (f + n-4 + filter(n-4))
= 4f + 4n-10 + filter(n-4)
= 5f + 5n-15 + filter(n-5)
...
我們可以概括爲x
重複?這1, 3, 6, 10, 15
...序列是三角形的數字 - 即1
,1+2
,1+2+3
,1+2+3+4
等所有號碼從1
到x
是x*(x-1)/2
總和。
= x*f + x*n - x*(x-1)/2 + filter(n-x)
現在,什麼是x
?我們會有多少次重複?那麼,你可以看到,當x
= n
,你沒有更多的遞歸 - filter(n-n)
= filter(0)
= 1
。因此,我們的公式現在是:
filter(n) = n*f + n*n - n*(n-1)/2 + 1
,我們可以進一步簡化:
filter(n) = n*f + n^2 - (n^2 - n)/2 + 1
= n*f + n^2 - n^2/2 + n/2 + 1
= n^2 - n^2/2 + f*n + n/2 + 1
= (1/2)n^2 + (f + 1/2)n + 1
因此,有雅有它 - 一個相當詳細的分析。那將是Θ((1/2)n^2 + (f + 1/2)n + 1)
...假設f
是不重要的(說f
= 1),得到Θ((1/2)n^2 + (3/2)n + 1)
。
現在你會發現,如果copy(n)
了一定量的時間,而不是時間的線性量(如果copy(n)
爲1,而不是n
),那麼你就不會得到在那裏n^2
項。
我承認,當我最初說Θ(n^2)
時,我並沒有在我的腦海裏這麼做。相反,我想:好的,你有n
遞歸步驟,並且由於copy
,每個步驟將花費n
時間量。 n*n = n^2
,因此Θ(n^2)
。要做到這一點有點更確切地說,n
縮小在每一步,讓您真正擁有n + (n-1) + (n-2) + (n-3) + ... + 1
,這最終是相同的圖如上:n*n - (1 + 2 + 3 + ... + n)
= n*n - n*(n-1)/2
= (1/2)n^2 + (1/2)n
,這是相同的,如果我用過的0
代替f
,上述。同樣,如果您有n
步驟,但每個步驟都需要1
而不是n
(如果您不需要複製該列表),那麼您將擁有1 + 1 + 1 + ... + 1
,n
次或簡單地n
。
但是,這需要更多的直覺,所以我想我還會告訴你可以應用於任何事情的蠻力方法。
'filter'中有多少次遞歸調用?它真的是'n * n'嗎? –
也許它實際上是Θ(n)。 – kayla
順便說一句,因爲'filter'與'reverse'一樣內置,所以你可以稱之爲'my_filter' – Claudiu