01 複雜度分析(上)

2022-07-06 13:06:10 字數 2734 閱讀 6862

**執行次數!

大 o 時間複雜度實際上並不具體表示**真正的執行時間,而是表示**執行時間隨資料規模增長的變化趨勢,所以,也叫作漸進時間複雜度(asymptotic time complexity),簡稱時間複雜度。當 n 很大時,你可以把它想象成 10000、100000。而公式中的低階、常量、係數三部分並不左右增長趨勢,所以都可以忽略。我們只需要記錄乙個最大量級就可以了。

分析雖然**千差萬別,但是常見的複雜度量級並不多。我稍微總結了一下,這些複雜度量級幾乎涵蓋了你今後可以接觸的所有**的複雜度量級。

對於剛羅列的複雜度量級,我們可以粗略地分為兩類,多項式量級和非多項式量級。

其中,非多項式量級只有兩個:o(2n) 和 o(n!)。我們把時間複雜度為非多項式量級的演算法問題叫作 np(non-deterministic polynomial,非確定多項式)問題。當資料規模 n 越來越大時,非多項式量級演算法的執行時間會急劇增加,求解問題的執行時間會無限增長。所以,非多項式時間複雜度的演算法其實是非常低效的演算法。因此,關於 np 時間複雜度我就不展開講了。我們主要來看幾種常見的多項式時間複雜度。

首先你必須明確乙個概念,o(1) 只是常量級時間複雜度的一種表示方法,並不是指只執行了一行**。我稍微總結一下,只要**的執行時間不隨 n 的增大而增長,這樣**的時間複雜度我們都記作 o(1)。或者說,一般情況下,只要演算法中不存在迴圈語句、遞迴語句,即使有成千上萬行的**,其時間複雜度也是ο(1)。

對數階時間複雜度非常常見,同時也是最難分析的一種時間複雜度。

i=1; 

while (i <=n)

這段**的時間複雜度就是 o(log2n)。

i=1; 

while (i <=n)

這段**的時間複雜度為 o(log3n)。 ------ 這裡是以3為底的對數表示.

實際上,不管是以 2 為底、以 3 為底,還是以 10 為底,我們可以把所有對數階的時間複雜度都記為 o(logn)。為什麼呢?

我們知道,對數之間是可以互相轉換的,log3n 就等於 log32 * log2n,所以 o(log3n) = o(c * log2n),其中 c=log32 是乙個常量。基於我們前面的乙個理論:在採用大 o 標記複雜度的時候,可以忽略係數,即 o(cf(n)) = o(f(n))。所以,o(log2n) 就等於 o(log3n)。因此,在對數階時間複雜度的表示方法裡,我們忽略對數的「底」,統一表示為 o(logn)。

如果你理解了我前面講的 o(logn),那 o(nlogn) 就很容易理解了。還記得我們剛講的乘法法則嗎?如果一段**的時間複雜度是 o(logn),我們迴圈執行 n 遍,時間複雜度就是 o(nlogn) 了。而且,o(nlogn) 也是一種非常常見的演算法時間複雜度。比如,歸併排序、快速排序的時間複雜度都是 o(nlogn)。

我們再來講一種跟前面都不一樣的時間複雜度,**的複雜度由兩個資料的規模來決定。老規矩,先看**!

int cal(int m, int

n)

int sum_2 = 0;

int j = 1;

for (; j < n; ++j)

return sum_1 +sum_2;

}

從**中可以看出,m 和 n 是表示兩個資料規模。我們無法事先評估 m 和 n 誰的量級大,所以我們在表示複雜度的時候,就不能簡單地利用加法法則,省略掉其中乙個。所以,上面**的時間複雜度就是 o(m+n)。針對這種情況,原來的加法法則就不正確了,我們需要將加法規則改為:t1(m) + t2(n) = o(f(m) + g(n))。但是乘法法則繼續有效:t1(m)*t2(n) = o(f(m) * f(n))。

前面,咱們花了很長時間講大 o 表示法和時間複雜度分析,理解了前面講的內容,空間複雜度分析方法學起來就非常簡單了。前面我講過,時間複雜度的全稱是漸進時間複雜度,表示演算法的執行時間與資料規模之間的增長關係。模擬一下,空間複雜度全稱就是漸進空間複雜度(asymptotic space complexity),表示演算法的儲存空間與資料規模之間的增長關係。

void print(int

n)

for (i = n-1; i >= 0; --i)

}

跟時間複雜度分析一樣,我們可以看到,第 2 行**中,我們申請了乙個空間儲存變數 i,但是它是常量階的,跟資料規模 n 沒有關係,所以我們可以忽略。第 3 行申請了乙個大小為 n 的 int 型別陣列,除此之外,剩下的**都沒有占用更多的空間,所以整段**的空間複雜度就是 o(n)。  我們常見的空間複雜度就是 o(1)、o(n)、o(n2 ),像 o(logn)、o(nlogn) 這樣的對數階複雜度平時都用不到。而且,空間複雜度分析比時間複雜度分析要簡單很多。所以,對於空間複雜度,掌握剛我說的這些內容已經足夠了。

複雜度也叫漸進複雜度,包括時間複雜度和空間複雜度,用來分析演算法執行效率與資料規模之間的增長關係,可以粗略地表示,越高階複雜度的演算法,執行效率越低。常見的複雜度並不多,從低階到高階有:o(1)、o(logn)、o(n)、o(nlogn)、o(n2 )。

複雜度分析並不難,關鍵在於多練。

01 複雜度分析(上) 時間 空間複雜度講解

我們都知道,資料結構和演算法本身解決的是 快 和 省 的問題,即如何讓 執行得更快,如何讓 更省儲存空間。所以,執行效率是演算法乙個非常重要的考量指標。那如何來衡量你編寫的演算法 的執行效率呢?這裡就要用到時間 空間複雜度分析。1 什麼是複雜度分析?複雜度也叫漸進複雜度,包括時間複雜度和空間複雜度,...

複雜度分析 上

1什麼是複雜度分析?分別用時間複雜度 執行的快慢 和空間複雜度 記憶體的消耗 兩個概念來描述效能問題,二者統稱為複雜度.複雜度就是用來分析演算法執行效率與資料規模之間增長關係。2.為什麼要進行複雜度分析?1.和效能測試相比,複雜度分析有不依賴執行環境 成本低 效率高 易操作 指導性強的特點。2.掌握...

複雜度分析(上)時間複雜度 空間複雜度

為了肉眼 實時 快速地來分析出 的複雜度,我們需要乙個不用具體的測試資料來測試,就可以粗略地估計演算法的執行效率的方法。時間複雜度 空間複雜度 表示演算法的執行時間與資料規模之間的增長關係。每行 對應的 cpu 執行的個數 執行的時間都不一樣,但是,我們這裡只是粗略估計,所以可以假設每行 執行的時間...