1. 程式人生 > >時間複雜度——大O演算法

時間複雜度——大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)等等。。。

參考:極客時間