數據結構和算法之時間複雜度和空間複雜度

前言

上一篇《數據結構和算法》中我介紹了數據結構的基本概念,也介紹了數據結構通常能夠分爲邏輯結構和物理結構。邏輯結構分爲集合結構、線性結構、樹形結構和圖形結構。物理結構分爲順序存儲結構和鏈式存儲結構。而且也介紹了這些結構的特色。而後,又介紹了算法的概念和算法的5個基本特性,分別是輸入、輸出、有窮性、肯定性和可行性。最後說闡述了一個好的算法須要遵照正確性、可讀性、健壯性、時間效率高和存儲量低。其實,實現效率和存儲量就是時間複雜度和空間複雜度。本篇咱們就圍繞這兩個"複雜度"展開說明。在真正的開發中,時間複雜度尤其重要,空間複雜度咱們不作太多說明。算法

時間複雜度

時間複雜度和空間複雜度是算法效率的度量方法。也就是說,一個好的算法取決於它的時間複雜度和空間複雜度。

函數的漸近增加:給定兩個函數f(n)和g(n),若是存在一個整數N,使得對於全部的n>N,f(n)老是比g(n)大。那麼,咱們說f(n)的增加漸近快於g(n)。數據結構

翻譯過來就是:若是存在一個臨界值,使得f(n)>g(n)永遠成立,那麼咱們就認爲"f(n)的增加漸近快於g(n)"。數據結構和算法

這裏我拿3個函數的增加曲線來講明問題。以下圖:函數

函數一:X = 3*n spa

函數二:Y = 2*n*n翻譯

函數三:Z = 2*n*n+3*ncode

當n=1時,Y < X < Z.blog

當n=2時,X < Y < Z.圖片

因此,存在一個值,這個值位於1和2之間,使得X < Y < Z永遠成立。咱們就稱Y的漸進增加快於X,Z的漸進增加快於Y,固然,根據傳遞性規則,Z的漸進增加也快於X。內存

定義

算法時間複雜度的定義:在進行算法分析時,語句總的執行次數T(n)是關於問題規模n的函數,進而分析T(n)隨n的變化狀況並肯定T(n)的數量級。

算法的時間複雜度,也就是算法的時間量度,記做:T(n)= O(f(n))。

它表示隨問題規模n的增大,算法執行時間的增加率和f(n)的增加率相同,稱做算法的漸近時間複雜度,簡稱爲時間複雜度。其中f(n)是問題規模n的某個函數。

時間複雜度計算方法

1.用常數1取代運行時間中的全部加法常數。

2.在修改後的運行次數函數中,只保留最高階項。

3.若是最高階項存在且不是1,則去除與這個項相乘的常數。

最後,獲得的最後結果就是時間複雜度。

常見的時間複雜度

按數量級遞增排列,常見的時間複雜度有:
常數階O(1),對數階O( log n ),線性階O(n),線性對數階O(nlog2n),平方階O(n^2),立方階O(n^3),...,k次方階O(n^k),指數階O(2^n)。隨着問題規模n的不斷增大,上述時間複雜度不斷增大,算法的執行效率越低。
也就是:
經常使用的時間複雜度所耗費的時間從小到大依次是: O(1) < O(logn) < (n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)

常數階

// 常數階
int n = 0;
printf(「oneSong」); printf(「oneSong」); printf(「oneSong」); printf(「oneSong」); printf(「oneSong」); printf(「oneSong」); printf(「oneSong」); printf(「oneSong」); printf(「oneSong」);

上面這段代碼的時間複雜度是O(1)。由於,按照時間複雜度的定義來講,n和問題的規模沒有關係。固然,按照時間複雜度計算方法第一條也能夠得出結果爲O(1)。

線性階

 
// 線性階
int i , n = 10086, sum = 0;
 
for( i=0; i < n; i++ )
{
    sum = sum + i;
}

上面這段代碼的時間複雜度是O(n),由於問題規模會隨着n的增加而變得愈來愈大,而且這種增加是線性的。

平方階

// 平方階
int i, j, n = 998;
 
for( i=0; i < n; i++ )
{
    for( j=0; j < n; j++ )
    {
        printf(「oneSong」);
    
}

上面這段代碼外層執行n次,外層循環每執行一次,內層循環就執行n次,那總共程序想要從這兩個循環出來,須要執行n*n次,也就是n的平方。因此這段代碼的時間複雜度爲O(n^2)。

對數階

// 對數階
int i = 1, n = 100;
 
while( i < n )
{
    i = i * 2;
}

因爲每次i*2以後,就距離n更近一步,假設有x個2相乘後大於或等於n,則會退出循環。因而由2^x = n獲得x = log(2)n,因此這個循環的時間複雜度爲O(logn)。

算法的空間複雜度

算法的空間複雜度經過計算算法所需的存儲空間實現,算法的空間複雜度的計算公式記做:S(n)=O(f(n)),其中,n爲問題的規模,f(n)爲語句關於n所佔存儲空間的函數。
在 程序開發中,咱們所指的複雜度不作特別說明的狀況下,就是指時間複雜度。如今的硬件發展速度之快使得咱們徹底能夠不用考慮算法所佔的內存,一般都是用空間 換取時間。加之算法的空間複雜度比較難算,因此,不管是在考試中仍是在項目開發中,咱們都側重於時間複雜度。因此,空間複雜度,略過。

圖片來源參考自:魚C工做室。感謝魚C工做室貢獻出了這麼好的圖片。
如非特別說明,筆者全部文章都是原創文章。若是您喜歡這篇文章,轉載請註明出處。若是您對數據結構感興趣,請關注我,後續會更新大量精品文章供你們參考!

PS:本篇文章在簡書也有同步更新,你們也能夠移步簡書關注本人,後續會更新更多精品文章!

簡書地址:http://www.jianshu.com/users/93131dfba96a/latest_articles

相關文章
相關標籤/搜索