算法的時間複雜度O

1、時間複雜度

  在進行算法分析時,語句總的執行次數 T(n) 是關於問題的規模n 的函數,進而分析 T(n) 隨 n 的變化狀況並肯定 T(n) 的數量級,算法的時間複雜度,也就是算法的時間度量,記做:T(n) = O(f( ))。它表示隨問題的規模 n 的增大,算法的執行時間的增加率 f(n) 的增加率相同,稱做算法的漸近時間複雜度,簡稱爲時間的複雜度,其中 f(n) 是問題規模n的某個函數。算法

    這樣用大寫 [ O( ) ] 來體現算法時間複雜度的記法,咱們就稱之爲大O記法。例如:O(n)、O(1)、O(n2)、O(log n) 等等。通常狀況下,隨着 n 的增大,T(n) 增加最慢的算法爲最優算法。數據結構

2、推導大O階的方法

1,用時間1取代運算時間中的全部加法常數。函數

2,在修改後的運行的函數中,只保留最高階項。spa

3,若是最高階項存在且不是1,則去除與這個項相乘的常數。獲得的結果就是大O階。code

例1:時間複雜度爲O(1)常數階的算法

1 int sum = 0, n = 100;    /* 執行一次 */
2 sum = (1+n) *n/2;        /* 執行一次 */
3 printf("the sum is:%d",sum);   /* 執行一次 */

  咱們能夠看出運行次數的函數是 f(n) = 3。根據咱們上面的大O階公式 1 能夠獲得,把常數項 3 改成 1,在保留最高階時發現沒有最高階項,因此時間複雜度爲大 O(1)。也就是說,不管算法是 3 次仍是 30 次,哪怕是 300 次,這些只要是常數項,它的時間複雜度都爲大 O(1),而不是O(3)、O(30)、O(300)。即咱們稱之爲常數階。blog

例2:時間複雜度爲O(n)線性階的算法

1 for(int i = 0; i < n; i++) { 2     sum += i; 3 }

  從上面的這段代碼咱們能夠看出,它的時間複雜度爲O(n),由於循環體中的代碼須要執行n次。排序

例3:時間複雜度爲O(n2)平方階的算法

1 for(int i = 0; i < n; i++) {
2     for(int j = i; j < n; j++) {
3         //時間複雜度爲O(n2)
4     }
5 }

分析:class

  當 i = 0時,內循環執行了 n 次,效率

  當 i = 1時,內循環執行了 n-1 次,循環

  ......

  當 i = n-1時。執行了 1 次,

  因此總的執行次數爲:n = (n-1)+(n-2)+ ··· + 1= n(n+1)/2 = n2/2+n/2。

  由上面的公式可得:第一條代碼中沒有加法常數項,不考慮;第二條只保留最高階項,所以保留 n2/2;第三條去除這個項相乘的常數,因此去除了 1/2;最終咱們獲得的代碼段時間複雜度就是 O(n2)。

例4:時間複雜度爲O(log n)對數階的算法

1 int count = 1; 2 while (count < n) { 3     count *= 2; 4 }

  上面代碼咱們能夠看出,count = count * 2 以後就距離 n 更近一步,也就是說,有多少個 2 相乘後大於 n,就退出循環。因此咱們能夠由 2x = n 推導出 x = log2n ,像這樣的循環時間複雜度,咱們就稱爲對數階的複雜度即爲 O(log n)。

3、O階算法效率排序

   數據結構中咱們通常經常使用的時間複雜度表示有:O(1)、O(n)、O(n2)、O(log n)、O(nlog n)、O(n3)、O(2n)。

  按時間複雜度所耗費的時間從大到小排序依次爲:

  O(1) < O(log n) < O(n) < O(nlog n) < O(n2) < O(n3) < O(2n)

相關文章
相關標籤/搜索