1什麼是複雜度分析?
分別用時間複雜度(執行的快慢)和空間複雜度(記憶體的消耗 )兩個概念來描述效能問題,二者統稱為複雜度.
複雜度就是用來分析演算法執行效率與資料規模之間增長關係。
2.為什麼要進行複雜度分析?
1.和效能測試相比,複雜度分析有不依賴執行環境、成本低、效率高、易操作、指導性強的特點。
2.掌握複雜度分析,將能編寫出效能更優的**,有利於降低系統開發和維護成本。
3.如何進行資料結構和演算法的複雜度分析?
1.大o表示法
1)**
演算法的執行時間與每行**的執行次數成正比,用t(n) = o(f(n))表示,其中t(n)表示演算法執行總時間,f(n)表示每行**執行總次數,而n往往表示資料的規模。
2)特點
以時間複雜度為例,由於時間複雜度描述的是演算法執行時間與資料規模的增長變化趨勢,所以常量階、低階以及係數實際上對這種增長趨勢不產決定性影響,所以在做時間複雜度分析時忽略這些項。
2.複雜度分析法則
1)單段**看高頻(只關注迴圈執行次數最多的一段**):比如迴圈。
1 int cal(int n)
7 return sum;
8 }
其中第 2、3 行**都是常量級的執行時間,與 n 的大小無關.4、5兩行為迴圈執行次數最多的一段**,
這兩行**執行了n次.所以複雜程度是o(n).
2)加法法則:總複雜度等於量級最大的那段**的複雜度:比如一段**中有單迴圈和多重迴圈,那麼取多重迴圈的複雜度。
1 int cal(int n)
7 int sum_2 = 0;
8 int q = 1;
9 for (; q < n; ++q)
1213 int sum_3 = 0;
14 int i = 1;
15 int j = 1;
16 for (; i <= n; ++i)
21 }
2223 return sum_1 + sum_2 + sum_3;
24 }
其中的4、5兩行執行了100次,與n無關.
段**迴圈 10000 次、100000 次,只要是乙個已知的數(常量,與n無關),就可以忽略.因為時間複雜度表示的是乙個演算法執行效率
與資料規模增長的變化趨勢.所以不管常量的執行時間對增長趨勢並沒有影響.
9、10兩段**的時間複雜程度是o(n),16、17、18、19的時間複雜程度是o(n2).所以這段**的時間複雜程度是o(n2).
3)乘法法則:巢狀**的複雜度等於巢狀內外**複雜度的乘積:比如遞迴、多重迴圈等
1 int cal(int n)
7 }
89 int f(int n)
15 return sum;
16 }
第 4~6 行的時間複雜度就是,t1(n) = o(n).但第五行的 f(i)函式本身就是 o(n),所以整個函式的複雜程度就是
t(n) = t1(n) * t2(n) = o(n*n) = o(n2)。
四、常用的複雜度級別
多項式階:隨著資料規模的增長,演算法的執行時間和空間占用,按照多項式的比例增長。包括,
o(1)(常數階)、o(logn)(對數階)、o(n)(線性階)、o(nlogn)(線性對數階)、o(n^2)(平方階)、o(n^3)(立方階)
非多項式階:隨著資料規模的增長,演算法的執行時間和空間占用暴增,這類演算法效能極差。包括,
o(2^n)(指數階)、o(n!)(階乘階)
1. o(1)
int i = 8;
int j = 6;
int sum = i + j;
o(1) 只是常量級時間複雜度的一種表示方法,並不是指只執行了一行**。比如這段**,即便有 3 行,
它的時間複雜度也是o(1),而不是 o(3)。
2. o(logn)、o(nlogn)
i=1;
while (i <= n)
這段**i<=n時結束,那麼就是2的i次方=n.求得時i的值.則x=log2n.時間複雜度就是 o(log2n)。
但是對數是可以相互轉換的.例如log3n 就等於 log32 * log2n.所以 o(log3n) = o(c * log2n),其中c=log32 是乙個常量.
在採用大 o 標記複雜度的時候,可以忽略係數,即 o(cf(n)) = o(f(n))。所以,o(log2n) 就等於 o(log3n)。
因此,在對數階時間複雜度的表示方法裡,我們忽略對數的「底」,,統一表示為 o(logn)。
那麼o(nlogn)就是迴圈執行一段時間複雜程度是o(logn)的**.
3. o(m+n)、o(m*n)
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))。
空間複雜度分析
空間複雜度全稱就是漸進空間複雜度(asymptotic space complexity),表示演算法的儲存空間與資料規模之間的增長關係。
1 void print(int n)
10 }
第3行申請了乙個大小為n的int型別陣列.其他的**沒有占用更多的空間.所以整段**的複雜程度就是o(n)
上面說了這麼多,但是沒有真正的用到有時候就不會真正的理解.所以想要真正的想要理解複雜分析度還是要多加練習.
複雜度分析(上)時間複雜度 空間複雜度
為了肉眼 實時 快速地來分析出 的複雜度,我們需要乙個不用具體的測試資料來測試,就可以粗略地估計演算法的執行效率的方法。時間複雜度 空間複雜度 表示演算法的執行時間與資料規模之間的增長關係。每行 對應的 cpu 執行的個數 執行的時間都不一樣,但是,我們這裡只是粗略估計,所以可以假設每行 執行的時間...
01 複雜度分析(上)
執行次數!大 o 時間複雜度實際上並不具體表示 真正的執行時間,而是表示 執行時間隨資料規模增長的變化趨勢,所以,也叫作漸進時間複雜度 asymptotic time complexity 簡稱時間複雜度。當 n 很大時,你可以把它想象成 10000 100000。而公式中的低階 常量 係數三部分並...
複雜度分析 時間複雜度分析和空間複雜度分析
其實,只要講到資料結構與演算法,就一定離不開時間 空間複雜度分析。而且我個人認為,複雜度分析是整個演算法學習的精髓,只要掌握了它,資料結構和演算法的內容基本上就掌握了一半。1.時間複雜度分析 對於剛才羅列的複雜度量級,我們可以粗略地分為兩類,多項式量級和非多項式量級。其中,非多項式量級只有兩個 o ...