對於算法分析最重要的是分析運行時間。在影響程序運行時間的因素中,除了某些超出所有理論模型范疇的因素諸如所使用的編譯器和計算器之外,主要的影響因素是所使用的算法和對該算法的輸入。
為了對運算時間進行簡化分析,我們采用約定:不存在特定的時間單位。因此我們拋棄一些前導的常數和低階項,從而計算大O的運行時間,由於大O是上界,絕不要低估程序的運行時間。
例:計算∑ i³
public static int sum(int n){
int sum;
⑴ sum = 0;
⑵ for(int i = 1; i <= n; i++){
⑶ sum += i * i * i;
}
⑷ return sum;
}
分析:所有的聲明均不計時間。第一行賦值語句和第四行返回值語句各占一個時間單位。第三行運行一次占4各時間單位(一次賦值,兩次乘法,一次加法),總共運行N次占4N個時間單位。第二行占(一次賦值,N+1次比較,N次自加)共2N+2個時間單位。忽略調用方法和返回值的開銷,得到總量是6N+4個時間單位。因此我們說該方法是O(N)的。
由於我們有了大O的結果,因此就存在許多可以采取捷徑而不影響最后運行結果的方法。例如在第三行中我們無需知道運行一次到底占幾個時間單位,我們只要知道它是O(1)的就行,至於賦值語句等與for循環比起可以忽略最后得到的結果還是O(N)。所以為了簡化分析,我們不必計較具體開銷,這使得我們得到一般法則。
法則一——for循環:
一個for循環運行時間至多是該for循環內部那些語句(包括測試)的運行時間乘以迭代次數。一般情況下由於大O內部任何簡化都是可能的,所以一般簡單的for循環得到的結果是O(N)的。
法則二——嵌套的for循環:
從里向外分析循環。在一組嵌套循環內部的一條語句運行時間為該語句的運行時間乘以該組所有的for循環大小的乘積。例如雙重for循環內部有一條賦值語句,則結果為O(N²)。
法則三——順序語句:
將各個語句的運行時間求和即可。(O(f(N))+O(g(N))= max(O(f(N)),O(g(N))
法則四——if / else語句:
對於程序片段
if(條件)
語句
else
語句
一個if / else語句的運行時間不會超過判斷的運行時間加上兩個語句中運行時間較長的那個語句的運行時間。