算法複雜度分析(上)

爲何須要算法複雜度分析?

首先,這和研究數據結構和算法的目的有關——「快」而「省」的解決問題。那麼如何衡量算法的性能呢?就須要算法複雜度分析。算法

其次,除了算法複雜度分析,還有一種方法能夠衡量複雜度,那就是「過後統計法」,即直接運行程序,統計須要的時間和空間。可是,這種方法有兩個問題:數組

1)結果很是依賴於測試環境。好比,用 Core i3 和用 Core i8 運行程序所需的時間是不一樣的;微信

2)結果受測試規模的影響特別大。好比,對有序數組進行排序的時間比對逆序數組排序的時間短;對於小規模數據而言,插入排序所需時間比快速排序要短。數據結構

因此,就須要有一種不用具體測試數據,也能估計算法執行效率的方法,就是算法複雜度分析,包括時間、空間複雜度分析。數據結構和算法

大 O 複雜度表示法

大 O 複雜度表示法能夠概括成下面一句話:函數

全部代碼的執行時間 T(n) 與每行代碼的執行次數 n 成正比。

T(n) = O(f(n))。其中,f(n) 表示代碼的執行次數之和。大 O 符號(Big O notation)是用於描述函數漸進行爲的數學符號,它表明「order of...」(...階)。性能

例如,對於代碼:測試

function foo (n) {
    var i = 0;
    var j = 0;
    for (; i < n; i++) {
        j += i;
    }
}

假設每行代碼的執行時間同樣,爲 unit_time。則第 二、3 行執行時間均爲 1 unit_time,第 四、5 行代碼執行時間均爲 n unit_time,整個函數的執行時間 T(n) = (2n + 2) * unit_time。用大 O 複雜度表示法表示即爲 T(n) = O(2n + 2)spa

注意,大 O 時間複雜度並不具體表示代碼真正的執行時間,而是表示代碼執行時間隨數據規模增加的變化趨勢。因此,它也叫漸進時間複雜度,簡稱時間複雜度。code

當 n 很大時,不左右增加趨勢的低階、常量、係數都可忽略。因此,上面例子中的時間複雜度爲 O(n)

時間複雜度分析

時間複雜度分析有下面幾個原則:

1)只關注循環執行次數最多的一段代碼;

2)加法原則:總複雜度等於量級最大的那段代碼的複雜度。用公式表示即爲:T1(n) = O(f(m)),T2(n) = O(g(n)),T1(n) + T2(m) = O(max(f(n), g(m)))

3)乘法原則:嵌套代碼的複雜度等於嵌套內外代碼複雜度的伺機。用公式表示即爲:T1(n) = O(f(m)),T2(n) = O(g(n)),T1(n) * T2(m) = O(f(n) * g(m))

常見的時間複雜度有如下幾種:

1)常量階:O(1)

2)對數階:O(logn)

3)線性階:O(n)

4)線性對數階:O(nlogn)

5)平方階:O(n ^ 2)

6)指數階:O(2 ^ n)

7)階乘階:O(n!)

其中,1)-5)爲多項式量級;6)、7)爲非多項式量級,所對應的算法問題被稱爲非肯定多項式問題(NP 問題,Non-Deterministic Polynomial)。

空間複雜度分析

空間複雜度全稱爲漸進空間複雜度(asymptostic space complexity)。空間複雜度較爲簡單,常見的空間複雜度爲 O(1)O(n)O(n ^ 2)

最後,用幾種複雜度的座標圖做爲結尾:


首發於微信公衆號《代碼寫完了》

相關文章
相關標籤/搜索