資料結構基礎學習之時間複雜度分析

h_dj發表於2019-04-05
一. 定義:

在進行演算法分析時,語句總的執行次數T(n) 是關於問題規模n的函式, 進而分析T(n) 隨 n 的變化情況並確認T(n) 的數量級。 演算法的時間複雜度,也是演算法的時間度量,記作:T(n) = O(f(n)). 它表示隨問題規模的增大,演算法執行時間的增長率和f(n) 的增長率相同 稱作演算法的漸近時間複雜度,簡稱時間複雜度. 其中f(n)是問題規模n 的 的某個函式

二. 推導大O階方法
  1. 用常數1 取代執行時間中的所有加法常數
  2. 在修改後的執行次數函式中, 只保留最高階項
  3. 如果最高階項相乘一個常數且不是1, 則去掉這個常數
1. 常數階時間複雜度 : O(1)
  1. 以下程式片段的時間複雜度函式 :f(n) = 1+1+1 = 3
  2. 根據推導大O階方法第一條: 用1 代替常數項
  3. 所以,時間複雜度為O(f(n)) = O(1); 稱為常數階
int sum = 0, n= 100;  //執行一次
int sum = 0, n= 100;  //執行一次
int sum = 0, n= 100;  //執行一次
複製程式碼
2. 線性階時間複雜度: O(n)
  1. 以下程式片段的時間複雜度函式 :f(n) = n
  2. 根據推導大O階方法第二條: 只保留最高階項
  3. 所以,時間複雜度為O(f(n)) = O(n); 稱為線性階
for (int i = 0; i < n ; i++) {
    System.out.println("i = "+i); // 執行n次
}
複製程式碼
3. 對數階時間複雜度 :O(logn)
  1. 以下程式片段的時間複雜度函式 :f(n) = log(2)n
  2. 所以,時間複雜度為O(f(n)) = O(logn); 稱為對數階
int count = 1; 
while(count < n ){
    // 每執行一次,count 乘 2 
    // 設x次後, count 大於 n ; 終止程式
    // 所以函式; 2^x = n   --> x = log(2)n
    count = count*2;  // 這裡執行 log(2)n 次
}
複製程式碼
4. 平方階時間複雜度:O(n^2)

example 1:

  1. 以下程式片段為雙重迴圈,所以執行次數為每個迴圈次數的乘積;時間複雜度函式 :f(n) = n^2
  2. 根據推導大O階方法第二條: 只保留最高階項
  3. 所以,時間複雜度為O(f(n)) = O(n^2),稱為平方階
for (int i = 0; i < n; i++) {
    for (int j = 0; j < n ; j++) {
         System.out.println("i = "+i+" j="+j);  //執行n*n次 
    }
}
複製程式碼

example 2:

  1. 以下程式片段時間複雜度函式 :f(n) = n^2/2+n/2
  2. 根據推導大O階方法第二條: 只保留最高階項 :f(n) = n^2/2
  3. 根據推導大O階方法第三條: 如果最高階項相乘一個常數且不是1, 則去掉這個常數:f(n) = n^2
  4. 所以, 時間複雜度為O(f(n)) = O(n^2),稱為平方階
for (int i = 0; i < n; i++) {
    for (int j = i; j < n ; j++) {
          // 注意; 內層的j = i,
          //所以,每次i 增加 1, 內層迴圈就減少一次
          // 則, 
          // 當i=0; 時,內層迴圈執行 n次
          // 當i=1時, 內層迴圈執行 n-1 次
          //....
          //當i=n-1, 內層迴圈執行 1 次
          // 所以,總執行次數相加為: n+(n-1)+(n-2)+...+1 = n(n+1)/2 【高斯求和】
         System.out.println("i = "+i+" j="+j);  
    }
}
複製程式碼
三、常見的時間複雜度
執行次數函式 非正式術語
12 O(1) 常數階
2n+3 O(n) 線性階
3n^2+2n+1 O(1) 平方階
5log(2)n+20 O(logn) 對數階
2n+3nlog(2)n+19 O(nlogn) nlogn階
6n^3+2n^2+3n+4 O(n^3) 立方階
2^n O(2^n) 指數階

相關文章