算法復雜度計算


上學的時候手把手教不會算,因為不會寫代碼,自打會寫了代碼之后,下面的一下子就能看懂了,用點心!!!

  • 在進行算法分析時,語句總的執行次數T(n)是關於問題規模n的函數,進而分析T(n)隨n的變化情況並確定T(n)的數量級。算法的時間復雜度,也就是算法的時間量度,記作:T(n}=0(f(n))。它表示隨問題規模n的增大,算法執行時間的埔長率和 f(n)的埔長率相同,稱作算法的漸近時間復雜度,簡稱為時間復雜度。其中f( n)是問題規橫n的某個函數。
    • 這樣用大寫O()來體現算法時間復雜度的記法,我們稱之為大O記法。一般情況下,隨着n的增大,T(n)增長最慢的算法為最優算法。
    • 之前我們說的三個求和算法的時間復雜度分別為0(n),0(1),0(n 2)。我就推一下吧。
    • 計算 1 + 2 + 3 + 4 + ...... + 100。代碼如下,之前也有講過:
    #include "stdio.h"
     
    int main()
    {
    int i, sum = 0, n = 100; /* 執行1次 */
    for( i = 1; i <= n; i++) /* 執行 n+1 次 */
    {
    sum = sum + i; /* 執行n次 */
    //printf("%d \n", sum);
    }
    printf("%d", sum); /* 執行1次 */
    }

 

    • 從代碼附加的注釋可以看到所有代碼都執行了多少次。那么這寫代碼語句執行次數的總和就可以理解為是該算法計算出結果所需要的時間。該算法所用的時間(算法語句執行的總次數)為: 1 + ( n + 1 ) + n + 1 = 2n + 3

      而當 n 不斷增大,比如我們這次所要計算的不是 1 + 2 + 3 + 4 + ...... + 100 = ? 而是 1 + 2 + 3 + 4 + ...... + n = ?其中 n 是一個十分大的數字,那么由此可見,上述算法的執行總次數(所需時間)會隨着 n 的增大而增加,但是在 for 循環以外的語句並不受 n 的規模影響(永遠都只執行一次)。所以我們可以將上述算法的執行總次數簡單的記做: 2n 或者簡記 n

      這樣我們就得到了我們設計的算法的時間復雜度,我們把它記作: O(n)

      再來看看高斯的算法:

          #include "stdio.h"
          int main()
          {
          int sum = 0, n = 100; /* 執行1次 */
          sum = (1 + n) * n/2; /* 執行1次 */
          printf("%d", sum); /* 執行1次 */
          }

       

    • 這個算法的時間復雜度: O(3),但一般記作 O(1)。

      從感官上我們就不難看出,從算法的效率上看,O(3) < O(n) 的,所以高斯的算法更快,更優秀。

        #include "stdio.h"
          int main()
          {
          int i, j, x = 0, sum = 0, n = 100; /* 執行1次 */
          for( i = 1; i <= n; i++)
          {
          sum = sum + i;
          //printf("%d \n", sum);
          for( j = 1; j <= n; j++)
          {
          x++; /* 執行n*n次 */
          sum = sum + x;
          }
          }
          printf("%d", sum); /* 執行1次 */
          }

       


      上面的代碼嚴格的說不能稱之為一個算法,畢竟它很“無聊而且莫名其妙”(畢竟算法是為了解決問題而設計的嘛),先不論這個“算法”能解決什么問題,我們看一下它的“大O階”如何推導,還是先計算一下它的執行總次數:

      執行總次數 = 1 + (n + 1) + n*(n + 1) + n*n + (n + 1) + 1 = 2n2 + 3n + 3

      如何推導大o階呢?我們給出了下面 的推導方法:

      1. 用常數1取代運行時間中的所有加法常數。
      2. 在修改后的運行次數函數中,只保留最髙階項。
      3. 如果最高階項存在且不是1,則去除與這個項相乘的常數。

      按照上面推導“大O階”的步驟我們先來第一步:“用常數 1 取代運行時間中的所有加法常數”,則上面的算式變為:執行總次數 = 2n^2 + 3n + 1

      第二步:“在修改后的運行次數函數中,只保留最高階項”。這里的最高階是 n 的二次方,所以算式變為:執行總次數 = 2n^2

      第三步:“如果最高階項存在且不是 1 ,則去除與這個項相乘的常數”。這里 n 的二次方不是 1 所以要去除這個項的相乘常數,算式變為:執行總次數 = n^2

      因此最后我們得到上面那段代碼的算法時間復雜度表示為: O( n^2 )

      • 最后我們在把常見的算法時間復雜度以及他們在效率上的高低順序記錄在這里,是大家對算法的效率有個直觀的認識。

      O(1) 常數階 < O(logn) 對數階 < O(n) 線性階 < O(nlogn) < O(n^2) 平方階 < O(n^3) < { O(2^n) < O(n!) < O(n^n) }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM