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


前言

上一篇《數據結構和算法》中我介紹了數據結構的基本概念,也介紹了數據結構一般可以分為邏輯結構和物理結構。邏輯結構分為集合結構、線性結構、樹形結構和圖形結構。物理結構分為順序存儲結構和鏈式存儲結構。並且也介紹了這些結構的特點。然后,又介紹了算法的概念和算法的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

函數二:Y = 2*n*n

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

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

當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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM