目錄
爲什麼進行時間複雜度分析?
因爲事後統計法有缺陷:①測速結果依賴測試環境②測試結果受數據規模的影響很大
需要一個不用具體的測試數據來進行粗略估計的方法。
大O複雜度表示法
T(n) =O(f(n))
T(n)表示代碼執行的時間,
n表示數據規模的大小,
f(n)表示每行代碼執行的次數總和。
公式中的O表示代碼的執行時間T(n)與f(n)表達式成正比。
大O時間複雜度實際上並不具體表示代碼真正的執行時間,而是表示代碼執行時間隨數據規模增長的變化趨勢,所以,也叫作漸進時間複雜度(asymptotic time complexity),簡稱時間複雜度。
時間複雜度分析
1、只關注循環執行次數最多的一段代碼
大O複雜度表示的是一種變化趨勢,在計算的時候會忽略常量、低階、係數,只需要記錄一個最大階的量級就好了。
我們在分析一個算法、一段代碼的時間複雜度的時候,也只關注循環執行次數最多的那一段代碼就可以了。
2、加法法則:總複雜度等於量級最大的那段代碼的複雜度
總的時間複雜度就等於量級最大的那段代碼的時間複雜度
T1(n)=O(f(n)),T2(n)=O(g(n));那麼T(n)=T1(n)+T2(n)=max(O(f(n)), O(g(n))) =O(max(f(n), g(n))).
3、乘法法則:嵌套代碼的複雜度等於嵌套內外代碼複雜度的乘積
T1(n)=O(f(n)),T2(n)=O(g(n));那麼 T(n)=T1(n)*T2(n)=O(f(n))*O(g(n))=O(f(n)*g(n)).
幾種常見的時間複雜度實例分析
可分爲:多項式量級和非多項式量級。其中,非多項式量級只有兩個:O(2n)和O(n!)。
把時間複雜度爲非多項式量級的算法問題叫作NP(Non-Deterministic Polynomial,非確定多項式)問題。
1、O(1)
O(1)只是常量級時間複雜度的一種表示方法,並不是指只執行了一行代碼。只要代碼的執行時間不隨n的增大而增長,這樣代碼的時間複雜度我們都記作O(1)。
一般情況下,只要算法中不存在循環語句、遞歸語句,即使有成千上萬行的代碼,其時間複雜度也是Ο(1)。
2、O(logn)、O(nlogn)
不管是以2爲底、以3爲底,還是以10爲底,我們可以把所有對數階的時間複雜度都記爲O(logn);
對數之間是可以互相轉換的,log3n就等於log32 * log2n,所以O(log3n) = O(C * log2n),其中C=log32是一個常量。在採用大O標記複雜度的時候,可以忽略係數,即O(Cf(n)) = O(f(n))。所以,O(log2n) 就等於O(log3n)。因此,在對數階時間複雜度的表示方法裏,我們忽略對數的“底”,統一表示爲O(logn)。
3、 O(m+n)、O(m*n)
代碼的複雜度由兩個數據的規模來決定。
m和n是表示兩個數據規模。我們無法事先評估m和n誰的量級大,所以我們在表示複雜度的時候,就不能簡單地利用加法法則,省略掉其中一個。所以,上面代碼的時間複雜度就是O(m+n)。
空間複雜度
空間複雜度全稱就是漸進空間複雜度(asymptotic space complexity),表示算法的存儲空間與數據規模之間的增長關係。
我們常見的空間複雜度就是O(1)、O(n)、O(n2 ),像O(logn)、O(nlogn)這樣的對數階複雜度平時都用不到
均攤時間複雜度
在數組中插入數據的這個例子。每一次O(n)的插入操作,都會跟着n-1次O(1)的插入操作,所以把耗時多的那次操作均攤到接下來的n-1次耗時少的操作上,均攤下來,這一組連續的操作的均攤時間複雜度就是O(1)。這就是均攤分析的大致思路。
對一個數據結構進行一組連續操作中,大部分情況下時間複雜度都很低,只有個別情況下時間複雜度比較高,而且這些操作之間存在前後連貫的時序關係,這個時候,我們就可以將這一組操作放在一塊兒分析,看是否能將較高時間複雜度那次操作的耗時,平攤到其他那些時間複雜度比較低的操作上。而且,在能夠應用均攤時間複雜度分析的場合,一般均攤時間複雜度就等於最好情況時間複雜度。均攤時間複雜度就是一種特殊的平均時間複雜度。
最好情況時間複雜度(best case time complexity)、最壞情況時間複雜度(worst case time complexity)、平均情況時間複雜度(average case time complexity)、均攤時間複雜度(amortized time complexity)。