資料結構之複雜度分析(二)

2021-09-24 03:55:34 字數 2674 閱讀 6366

一. 什麼是複雜度分析

二. 為什麼需要複雜度分析

三. 如何進行複雜度分析

空間複雜度

四. 複雜度分析的細化

衡量一段**的執行效率最主要的無非是「快」、「省」,其中快是指執行速度快,省是指占用空間少。這裡所指的複雜度分析指的是時間、空間複雜度。我們常說的以空間換取時間也正是對應這兩點。

時間複雜度:**執行時間隨著資料量規模增長的變化趨勢,這個時間不是**的真正執行時間,所以也叫漸近時間複雜度。也可以簡單認為時間複雜度就是對乙個演算法執行所需時間的度量,用大o表示法表示。

空間複雜度:同時間複雜度類似,表示的是漸近空間複雜度,簡稱空間複雜度,表示的是**執行所需臨時儲存空間隨著資料量規模增長而形成的變化趨勢。也可以簡單認為空間複雜度就是對乙個演算法執行所需臨時空間的度量,用大o表示法表示。

資料結構與演算法解決的也就是「快」、「省」的問題,因此談到資料結構就少不了複雜度分析了。

也許你會說直接執行**進行測試不也就直接得出相關的複雜度了麼?首先要確定這種方法在一定程度上是對的。但這種方法有一定的侷限性:比如受限於執行環境,執行的資料量。因此我們就需要乙個不依賴於執行環境與資料量便可粗略得出程式的執行複雜度的衡量方法,而這個方法正好就是時間、空間複雜度分析。和效能測試相比,複雜度分析有不依賴執行環境、成本低、效率高、易操作、指導性強的特點。掌握複雜度分析,將能編寫出效能更優的**,有利於降低系統開發和維護成本。

複雜度分析的推導過程:

下面以乙個簡單例子來說明時間複雜度

int cal(int n) 

return sum;

}

因為時間複雜度分析並非指**實際執行的時間,只是表示**的執行時間與執行資料量的變化趨勢,因此這裡可以假設每行**的執行時間為unit_time。由上述**可知,第2,3行總代執行了兩次,第4,5行總共執行了2n次,那麼**總的執行時間便可表示為(2+2n)* unit_time。這裡可以看出所有**總的執行時間t(n) 與**執行的次數成正比。

按照這個思路再進行分析如下**:

int cal(int n) }}

根據上個例子可以簡單分析上述**執行所需時間如下:第2,3,4行共需3unit_time, 第5,6行需要2*n* unit_time, 第7,8行為巢狀迴圈因此所需 2*n*n* unit_time,故該**所需要時間為 (2n*n + 2n + 3)* unit_time。

儘管我們不知道unit_time的實際值,但是通過上述兩段**的推導過程,我們可以得出乙個很重要的規律,也就是所有**所需要的執行時間t(n)與每行**所執行的次數成正比。

這裡便引出大o表示法,也是時間複雜度的官方定義。

演算法的執行時間與每行**的執行次數成正比,用t(n) = o(f(n))表示,其中t(n)表示演算法執行總時間,f(n)表示每行**執行總次數,而n往往表示資料的規模。

由於o(n)表示的是**執行時間與資料量形成的增長趨勢,因此對於乙個表示式中對整體趨勢沒有起決定性影響的等項直接忽視掉。一般有如下原則:

如果執行時間是常數量級的,則統一用o(1) 表示;

只保留最高端項,並且省掉最高端項前面的係數。

根據上述原則,示例一 t(n)=(2+2n)* unit_time 對應的大o表示法便是 o(n),示例二 t(n)=(2n*n + 2n + 3)* unit_time 便是 o(n*n)。

void print(int n) 

}

與時間複雜度分析同理,分析上述**第2行給 i額外分配了乙個儲存空間,該空間為常量階,因此對於增長趨勢的影響可忽略,第3行給陣列 a額外分配了大小為 n 的儲存空間,其他基本沒有占用太多空間,由於該**的空間複雜分析為 o(n)。

常見的複雜度有如下

上圖可分為多項式與非多項式階,其中非多項式階隨著資料規模的增長,演算法的執行時間和空間占用暴增,這類演算法效能極差,也就是常說的np問題。包括,o(2^n)(指數階)、o(n!)(階乘階)。

對於同一段**在不同情況下時間複雜度會出現量級差異,為了更全面,更準確的描述**的時間複雜度,所以引入這4個概念。但是在大多數情況下,是不需要區別分析它們的。

最壞情況時間複雜度:**在最理想情況下執行的時間複雜度。

最好情況時間複雜度:**在最壞情況下執行的時間複雜度。

平均時間複雜度:用**在所有情況下執行的次數的加權平均值表示。

均攤時間複雜度:在**執行的所有複雜度情況中絕大部分是低階別的複雜度,個別情況是高階別複雜度且發生具有時序關係時,可以將個別高階別複雜度均攤到低級別複雜度上。基本上均攤結果就等於低級別複雜度。

總的來說:在分析時間複雜度是o(1)還是o(n)的時候最簡單就是憑感覺,出現o(1)的次數遠大於出現o(n)出現的次數,那麼平均平攤時間複雜度就是o(1)。

可參考:漫畫:什麼是時間複雜度?

該系列博文為筆者學習《資料結構與演算法之美》的個人學習筆記小結

資料結構之複雜度分析

目錄 1 為什麼需要複雜度分析?2 大o複雜度表示法 3 時間複雜度 3.1 只關注迴圈執行次數最多的一段 3.2 總的複雜度等於量級最大的那段 的複雜度 加法法則 3.3 巢狀 的複雜度等於巢狀內外 複雜度的乘積 乘法法則 3.4 時間複雜度 4 空間複雜度 5 時間複雜度擴充套件 網上一直有乙個...

資料結構系列之複雜度分析

1 時間複雜度 求解演算法的時間複雜度的具體步驟是 找出演算法中的基本語句 演算法中執行次數最多的那條語句就是基本語句,通常是最內層迴圈的迴圈體。計算基本語句的執行次數的數量級 只需計算基本語句執行次數的數量級,這就意味著只要保證基本語句執行次數的函式中的最高次冪正確即可,可以忽略所有低次冪和最高次...

演算法分析之複雜度

時間複雜度 是度量演算法執行的時間長短或者說是程式執行的次數。詳細說明 乙個演算法,處理n條資料需要的時間可以用表示式 a n b來表示的話,稱它的時間複雜度為o n 也就是說,100條資料需要1秒的話,1000條資料需要10s。如果是用表示式 a n n b n c的話,複雜度為o n的平方 這樣...