資料結構和演算法之美筆記 複雜度分析

2021-10-14 01:45:51 字數 3897 閱讀 9045

目錄

一、時間複雜度 時間複雜度的全稱是漸進時間複雜度,表示演算法的執行時間與資料規模之間的增長關係

二、時間複雜度分析

1. 只關注迴圈執行次數最多的一段**

2. 加法法則:總複雜度等於量級最大的那段**的複雜度 3

. 乘法法則:巢狀**的複雜度等於巢狀內外**複雜度的乘積

二、常見的時間複雜度量級

1. o(1):只要**的執行時間不隨 n 的增大而增長,這樣**的時間複雜度我們都記作 o(1)。

2. o(logn)、o(nlogn)

3. o(m+n)、o(m*n):**的時間複雜度由兩個資料的規模來決定

三、空間複雜度分析:空間複雜度全稱就是漸進空間複雜度,表示演算法的儲存空間與資料規模之間的增長關係 常見的空間複雜度就是 o(1)、o(n)、o(n2 )

複雜度大小關係

四、最好情況時間複雜度、最壞情況時間複雜度、平均情況時間複雜度

1、平均時間複雜度或者期望時間複雜度

2、均攤時間複雜度

資料結構和演算法之美 - 03

大 o 時間複雜度實際上並不具體表示**真正的執行時間,而是表示**執行時間隨資料規模增長的變化趨勢,所以,也叫作漸進時間複雜度(asymptotic time complexity),簡稱時間複雜度。

1、假設每行**執行的時間都一樣,為 unit_time(乙個單位時間)

1.int cal(int n) 

7. return sum;

8. }

2、假設每行**執行的時間都一樣,為 unit_time(乙個單位時間)

1.int cal(int n) 

10. }

11. }

整段**的時間複雜度就為 o(n2)。也就是說:總的時間複雜度就等於量級最大的那段**的時間複雜度。

int cal(int n) 

int sum_2 = 0;

int q = 1;

for (; q < n; ++q)

int sum_3 = 0;

int i = 1;

int j = 1;

for (; i <= n; ++i)

}return sum_1 + sum_2 + sum_3;

}

int cal(int n)  

} int f(int n)

return sum;

}

分為兩類,多項式量級和非多項式量級。其中,非多項式量級只有兩個:o(2^n) 和 o(n!)

當資料規模 n 越來越大時,非多項式量級演算法的執行時間會急劇增加,求解問題的執行時間會無限增長。所以,非多項式時間複雜度的演算法其實是非常低效的演算法。

從**中可以看出,變數 i 的值從 1 開始取,每迴圈一次就乘以 2。當大於 n 時,迴圈結束。還記得我們高中學過的等比數列嗎?實際上,變數 i 的取值就是乙個等比數列。如果我把它乙個乙個列出來,就應該是這個樣子的:

所以,我們只要知道 x 值是多少,就知道這行**執行的次數了。通過 2x=n 求解 x ,x=log2n,所以,這段**的時間複雜度就是 o(log2n)。

以下時間複雜度為o(log3n)

i=1;

while (i <= n)

實際上,不管是以 2 為底、以 3 為底,還是以 10 為底,我們可以把所有對數階的時間複雜度都記為 o(logn)從**中可以看出,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))。

int cal(int m, int n) 

int sum_2 = 0;

int j = 1;

for (; j < n; ++j)

return sum_1 + sum_2;

}

跟時間複雜度分析一樣:

所以整段**的空間複雜度就是 o(n),但實際應用過程中我們說

空間複雜度

的時候,是指除了原本的資料儲存空間外,演算法執行還需要額外的儲存空間。這裡儲存資料需要乙個大小為 n 的陣列,這 n 個空間是必須的,無法省掉。在**操作過程中只需要乙個臨時變數儲存空間,所以空間複雜度是 o(1)。

資料結構與演算法之美-04

// n表示陣列array的長度

int find(int array, int n, int x)

} return pos;

}

要查詢的變數 x 可能出現在陣列的任意位置。

所以,不同的情況下,這段**的時間複雜度是不一樣的。為了表示**在不同情況下的不同時間複雜度,我們需要引入三個概念:最好情況時間複雜度、最壞情況時間複雜度和平均情況時間複雜度。

最好情況時間複雜度就是,在最理想的情況下,執行這段**的時間複雜度。

最壞情況時間複雜度就是,在最糟糕的情況下,執行這段**的時間複雜度。

最好情況時間複雜度和最壞情況時間複雜度對應的都是極端情況下的**複雜度,發生的概率其實並不大。為了更好地表示平均情況下的複雜度,我們需要引入另乙個概念:平均時間複雜度

要查詢的變數 x,要麼在陣列裡,要麼就不在陣列裡。這兩種情況對應的概率統計起來很麻煩,我們假設在陣列中與不在陣列中的概率都為 1/2。另外,要查詢的資料出現在 0~n-1 這 n 個位置的概率也是一樣的,為 1/n。所以,根據概率乘法法則,要查詢的資料出現在 0~n-1 中任意位置的概率就是 1/(2n)。因此,前面的推導過程中存在的最大問題就是,沒有將各種情況發生的概率考慮進去。如果我們把每種情況發生的概率也考慮進去,那平均時間複雜度的計算過程就變成了這樣:

這個值就是概率論中的加權平均值,也叫作期望值,所以平均時間複雜度的全稱應該叫加權平均時間複雜度或者期望時間複雜度。

對乙個資料結構進行一組連續操作中,大部分情況下時間複雜度都很低,只有個別情況下時間複雜度比較高,而且這些操作之間存在前後連貫的時序關係,這個時候,我們就可以將這一組操作放在一塊兒分析,看是否能將較高時間複雜度那次操作的耗時,平攤到其他那些時間複雜度比較低的操作上。而且,在能夠應用均攤時間複雜度分析的場合,一般均攤時間複雜度就等於最好情況時間複雜度。

例如:每一次 o(n) 的插入操作,都會跟著 n-1 次 o(1) 的插入操作,所以把耗時多的那次操作均攤到接下來的 n-1 次耗時少的操作上,均攤下來,這一組連續的操作的均攤時間複雜度就是 o(1)。例如棧的動態擴容

資料結構與演算法之美 複雜度分析

因為我們需要乙個不用具體的測試資料來測試,就可以粗略估計演算法的執行效率的方法。演算法的執行效率,粗略地講,就是演算法 執行的時間。舉個例子 int cal int n 首先,所有 的執行時間 t n 與每行 的執行次數成正比。我們依舊假設每個語句的執行時間是 unit time。那這段 的總執行時...

資料結構之演算法複雜度

解決特定問題求解步驟的描述。在計算機中表現為指令的有限序列,每條指令可表示乙個或多個操作。此外,乙個演算法還具有下列5個特性 有窮性,確定性,可行性,輸入,輸出。演算法設計的要求 正確性,可讀性,健壯性,效率與低儲存量需求。what?時間複雜度和空間複雜度 why?可以用度量演算法的好與壞 how?...

資料結構和演算法 複雜度

演算法複雜度 1 時間複雜度 表示演算法的執行時間與資料規模之間的增長關係 1 只關注迴圈執行次數最多的一段 2 加法法則 總複雜度等於量級最大的那段 的複雜度 3 乘法法則 巢狀 的複雜度等於巢狀內外 複雜度的乘積 幾種常見時間複雜度例項分析 最好 最壞 平均 均攤時間複雜度要根據具體的演算法進行...