時間複雜度 - 簡單易懂

本文對時間複雜度進行簡單的講解,主要在於簡單易懂。算法

1、算法效率的度量方法

一、過後統計方法swift

計算機 運行設計好的 測試算法的 程序和數據,獲得運行時間。函數

缺陷:花時間 寫 算法的測試程序。性能

測試用的計算機性能有差異。編譯器產生的代碼質量。問題的輸入規模。測試

二、事前分析估算方法優化

依據統計方法對算法進行估算。spa

一個程序的運行時間依賴於算法的好壞和問題的輸入規模。(問題的輸入規模 是指輸入量的多少)設計

 

2、簡單分析日誌

先看兩端代碼(本文demo是新建一個playground來寫的,用的swift),咱們求1到n的和,能夠用for循環從1加到n,也能夠用公式:(n + 1) * n / 2 來算。以下:blog

一、第一種算法:

請點擊此處輸入圖片描述

二、第二種算法:

請點擊此處輸入圖片描述

三、分析

上面兩種算法,第一種要執行100次,而第二種只用執行一次。很明顯,第二種要比第一種效率更高。那麼到底怎麼來表示這兩種算法的效率呢,那就是時間複雜度。

算法的複雜度 不是精確的定位須要執行多少次,好比你在第二種算法中打印一萬第二天志,那第二種算法是否是就很差了呢。 咱們看的不是具體執行的行數,而是第一種循環了多少次,而第二種只須要一次執行。

若是看具體執行多少次語句,就要考慮編譯器優化等問題,語言的優劣,無關代碼等。

因此算法的複雜度 側重研究算法隨着 輸入規模擴大 而增加的一個抽象。不計 變量聲明、打印日誌、循環索引的遞增和循環終止的條件 等。

在分析一個算法的運行時間時,重要的是把基本操做的數量和輸入模式 關聯起來。

上面2種方法隨着n的增大,執行的時間比 分別增加了n倍,和沒有變。因此咱們能夠理解爲他們的複雜度分別爲n 和 1。

若是兩個嵌套for循環的話,效率又是多少呢?以下:

請點擊此處輸入圖片描述

上面這個 外面每執行一次,裏面就執行n次。因此效率是n*n。

 

3、算法的複雜度如何分析

上面只是簡單的說了3個例子,下面咱們說下算法複雜度的分析方法。

一、忽略 加法常數

A算法: 2n+3

B算法:3n+1

當n不斷變大的時候:2n+3 基本和 2n 相同。 3n+1和 3n 基本相同。後面的加法常數 基本沒有影響。

因此時間複雜度要 忽略 加法常數。

二、忽略 相乘常數

4n 和 2n^2

當n不斷變大的時候:

其實 就是 n 和 n^2 的趨勢結果。

因此:於最高次項相乘的常數 並不重要,也能夠忽略。不影響算法比較。

三、保留最高次項

2n^2+3n+1 和 2n^3+3n+1:

其實就是 n^2 和 n^3 的趨勢結果。

最高次項的 指數,函數隨着n的增加,結果也會變得增加特別快。

四、保留最高項階數

2n^2+3n+1 和 2n^2 ,當n變大,這兩個值幾乎相同。

判斷算法的效率時,函數中的常數和其餘次要項經常能夠忽略,而更應該關注主項(最高項)的階數。

4、算法時間複雜度

一、算法時間複雜度 的定義

下面是官方的定義,你們看看,若是以爲很差理解,就往下面看就行了。

在進行算法分析時,語句總的執行次數T(n) 是關於問題規模n的函數。

進而分析T(n)隨n的變化狀況而肯定T(n)的數量級。

算法的時間複雜度,也就是算法的時間量度。記做:T(n)=O(f(n))

它表示隨問題規模n的增大,算法執行時間的增加率和 f(n) 的增加率相同,稱做算法的漸進時間複雜度,簡稱爲時間複雜度。 其中 f(n)是問題規模n的某個函數。

這樣用 大寫O() 體現時間複雜度 的記法, 稱爲:大O記法。

隨着輸入規模 n 的增大,T(n)增加最慢的算法爲最優算法。

文章開始的 三個求和算法的例子 (1 、 n 、n^2 )的時間複雜度 分別爲: O(1) , O(n) , O(n^2)

二、如何分析一個算法的時間複雜度

2.一、用常數1 取代運行時間中的全部加法常數。

2.二、最修改後的運行次數函數中,只保留最高階項

2.三、若是最高階存在且不是1,則去除與這個項相乘的常數。

 

5、實戰分析

一、 下面代碼的時間複雜度是多少?

請點擊此處輸入圖片描述

是 O(4) ?

是錯的。只有O(1)。沒有O(2)、O(3)、O(4).

T(n) 是關於問題規模n的函數。print 和 n 是沒有關係的。因此答案是O(1)。

二、分析下面代碼的時間複雜度

請點擊此處輸入圖片描述

執行的次數:

n+(n-1)+(n-2)+….+1 = n(n+1)/2

分解:

n(n+1)/2 = n^2

根據剛纔的 策略:

只保留最高項:因此 n/2 這項去掉。

去除與最高項相乘的常數:最終爲: O(n^2)

三、對階數

請點擊此處輸入圖片描述

若是 有 X個2 相乘 後 >= n , 則會退出循環。

因而由 2^X = n 獲得: X = log(2)n 。

因此 這個時間複雜度爲 O(logn)

在各類不一樣算法中,若算法中語句執行次數爲一個常數,則時間複雜度爲O(1)。

另外,在時間頻度不相同時,時間複雜度有可能相同,如T(n)=n2+3n+4與T(n)=4n2+2n+1它們的頻度不一樣,但時間複雜度相同,都爲O(n2)。

按數量級遞增排列,常見的時間複雜度有:常數階O(1),對數階O(log2n),線性階O(n), 線性對數階O(nlog2n),平方階O(n2),立方階O(n3),..., k次方階O(nk),指數階O(2n)。隨着問題規模n的不斷增大,上述時間複雜度不斷增大,算法的執行效率越低。

四、最好、最差、平均 複雜度

舉例:在冒泡排序中,若是給的數據原本就是排好序的,那麼用冒泡排序 只須要執行n次就能夠完成。也就是最好時間複雜度爲 O(n)。

通常咱們說的算法複雜度的平均 就是最差的狀況。也就是O(n2)。

因此 冒泡排序 的 最差、平均 時間複雜度: O(n2) 。最好時間複雜度: O(n)

相關文章
相關標籤/搜索