一般情況下,演算法的基本操作重複執行的次數是模組n的某一函式f(n),因此,演算法的時間複雜度記做 t(n) = o(f(n))。 隨著模組n的增大,演算法執行的時間增長率f(n)的增長率成正比,所以f(n)越小,演算法的時間複雜度越低,演算法的效率越高。
時間複雜度是總運算次數表示式中受n的變化影響最大的那一項(不含係數)
舉個簡單的例子:
int
value = 0; // 執行了1次
for (int i = 0; i < n; i++)
這個演算法執行了 1 + n 次,如果n無限大,我們可以把前邊的1忽略,也就是說這個演算法執行了n次。時間複雜度常用大o符號表示,這個演算法的時間複雜度就是o(n)。
計算出基本操作的執行次數t(n)
基本操作即演算法中的每條語句(以;號作為分割),語句的執行次數也叫做語句的頻度。在做演算法分析時,一般預設為考慮最壞的情況。
用大o來表示時間複雜度
當n趨近於無窮大時,如果lim(t(n)/f(n))的值為不等於0的常數,則稱f(n)是t(n)的同數量級函式。記作t(n)=o(f(n))。
只保留最高端項,最高端項存在且不是1,則去除與這個項相乘的常數。
用乙個例子來表明以上的步驟:
for(i=1;i<=n;++i)
}
第一步計算基本語句執行次數:t(n)= n^2+n^3;
第二步t(n)的同數量級,我們可以確定 n^3為t(n)的同數量級;
第三步用大o表示時間複雜度:t(n)=o(n^3)。
執行次數函式階名稱
3o(1)
常數階2n+3
o(n)
線性階3n2+2n+1
o(n2)
平方階5log2n+2
o(log2n)
對數階2n+3nlog2n+1
o(nlogn)
nlog2n階
6n3+2n2+3n+4
o(n3)
立方階2n
o(2n)
指數階
最常見的多項式時間演算法複雜度關係為:
o(1) < o(logn) < o(n) < o(nlogn) < o(n2) < o(n3)
指數時間演算法複雜度關係為:
o(2n) < o(n!)< o(nn)
舉個例子來說明上述的時間複雜度:
i=1; // 執行次數:1
while (i<=n)
i=i*2;
// 頻度為f(n),2^f(n)<=n;f(n)<=log2n
// 每次i*2後,距離結束迴圈更近了。也就是說有多少個2相乘後大於n。
// 取最大值f(n)=log2n,t(n)=o(log2n )
1.並列迴圈複雜度分析
for (i=1;
i<=n;
i++)
for (j=1;
j<=n;
j++)
x++; //o(n2)
2.函式呼叫的複雜度分析
public
void printsum(int
count)
system.out.print(sum);
}
記住,只有可執行的語句才會增加時間複雜度,因此,上面方法裡的內容除了迴圈之外,其餘的可執行語句的複雜度都是o(1)。
所以printsum的時間複雜度 = for的o(n)+o(1) = 忽略常量 = o(n)
空間複雜度(space complexity)是對乙個演算法在執行過程中臨時占用儲存空間大小的量度,記做s(n)=o(f(n))。
比如直接插入排序的時間複雜度是o(n^2),空間複雜度是o(1) 。而一般的遞迴演算法就要有o(n)的空間複雜度了,因為每次遞迴都要儲存返回資訊。
例如關於o(1)的問題, o(1)是說資料規模和臨時變數數目無關,並不是說僅僅定義乙個臨時變數。舉例:無論資料規模多大,我都定義100個變數,這就叫做資料規模和臨時變數數目無關。就是說空間複雜度是o(1)。
一文帶你搞懂演算法時間複雜度
乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時間多,哪個演算法花費的時間少就可以了。並且乙個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數多,它花費時間就多。乙個演算法...
一文搞定時間複雜度和空間複雜度
寫在前面 博主是一位普普通通的19屆雙非軟工在讀生,平時最大的愛好就是聽聽歌,逛逛b站。博主很喜歡的一句話花開堪折直須折,莫待無花空折枝 博主的理解是頭一次為人,就應該做自己想做的事,做自己不後悔的事,做自己以後不會留有遺憾的事,做自己覺得有意義的事,不浪費這大好的青春年華。博主寫部落格目的是記錄所...
演算法的複雜度 時間複雜度與空間複雜度
通常,對於乙個給定的演算法,我們要做 兩項分析。第一是從數學上證明演算法的正確性,這一步主要用到形式化證明的方法及相關推理模式,如迴圈不變式 數學歸納法等。而在證明演算法是正確的基礎上,第二步就是分析演算法的時間複雜度。演算法的時間複雜度反映了程式執行時間隨輸入規模增長而增長的量級,在很大程度上能很...