時間複雜度——大O演算法
演算法的執行效率,就是演算法程式碼的執行時間。我們需要能夠用肉眼就看出一段程式碼的執行時間。
int cal(int n){
int sum = 0;
int i = 1;
for(; i<=n; ++i){
sum=sum+1;
}
return sum;
}
2,3行都執行了1個unit_time的執行時間,4,5行都運行了n遍,所以是2n*unit_time的執行時間,所以一共是(2n+2)*unit_time。所有的程式碼的執行時間T(n)與每行程式碼的執行次數成正比。
T(n)=O(f(n))
T(n)表示程式碼的執行時間;n表示資料規模的大小;f(n)表示每行程式碼執行的次數總和,T(n) = O(2n+2),這就是大O時間複雜度表示法。大O時間複雜度實際上並不具體表示程式碼真正的執行時間,而是表示程式碼執行時間歲資料規模增長的變化趨勢,所以,也叫作漸進時間複雜度。
而我們只需要記錄一個最大量級就可以了。
時間複雜度分析
1.只關注迴圈執行次數最多的一段程式碼
我們通常可以忽略掉工事中的敞亮,低階,係數,只需要記錄一個最大階的量級即可。
int cal(int n){
int sum = 0;
int i = 1;
for(; i<=n; ++i){
sum=sum+1;
}
return sum;
}
還是這個例子,2,3行都是常量級別的,4,5行是迴圈執行次數最多的,這兩行程式碼被執行了n次,所以總的時間複雜度是O(n)
加法規則:總複雜度等於量級最大的那段程式碼的複雜度
舉個例子:
int cal(int n) { int sum_1 = 0; int p = 1; for (; p < 100; ++p) { sum_1 = sum_1 + p; } int sum_2 = 0; int q = 1; for (; q < n; ++q) { sum_2 = sum_2 + q; } int sum_3 = 0; int i = 1; int j = 1; for (; i <= n; ++i) { j = 1; for (; j <= n; ++j) { sum_3 = sum_3 + i * j; } } return sum_1 + sum_2 + sum_3; }
這個程式碼分三個部分,分別是求sum_1,sum_2,sum_3。分析每一部分的時間複雜度,然後再把他們放在一塊,再取一個量級最大的作為整段程式碼的複雜度。
第一段是一個常量;第二段是O(n);第三段是O(n^2)
所以取最高的O(n^2).
3.乘法法則:巢狀程式碼的複雜度等於巢狀內外程式碼複雜度的乘積
int cal(int n) { int ret = 0; int i = 1; for (; i < n; ++i) { ret = ret + f(i); } } int f(int n) { int sum = 0; int i = 1; for (; i < n; ++i) { sum = sum + i; } return sum; }
單獨看cal()函式,假設f()只是一個普通函式,那麼4-6行就是O(n),但是f()本身並不是一個簡單的操作,他的時間複雜度是O(n),所以,整個cal()函式的時間複雜度就是,T1(n)T2(n)=O(nn)=O(n^2)
比較常見的演算法時間複雜度:O(1),O(logn),O(nlogn),O(2^n),
O(n^k)等等。。。
參考:極客時間