注意:本文摘自《數據結構——從概念到C實現》【王紅梅 皮德常 編著】
目錄
算法效率分析
度量算法的效率有兩種方法
一,事後統計,先實現算法,再輸入數據來測量其時間,空間開銷。此種方法的缺點至少有
- 編寫程序實現算法很耗費時間精力
- 實驗結果依賴於計算機的軟硬件等環境因素,有時很容易掩蓋算法本身的優劣。
二,事前分析估計,漸進複雜度估算,這是對算法所消耗資源的一種估算方法。
算法的時間複雜度
同一個算法用不同的程序設計語言實現,或者用不同的編譯程序進行編譯,或者在不同的計算機上運行,效率均不相同。撇開與計算機軟硬件有關的因素,影響算法時間代價的最主要因素是問題規模。問題規模是指輸入量的多少,一般來說,它可以從問題的描述中得到。例如,找出100以內的所有素數,問題規模是100;對一個具有n個整數的數組進行排序,問題規模是n。一個顯而易見的事實是:幾乎任何算法對於規模更大的輸入需要運行更長的時間。例如,找出1000內所有的素數比找出100內所有的素數需要更多的時間。所以,運行算法所需要的時間T是問題規模n的函數,記作T(n)。
要精確地表示算法的運行時間函數常常是很困難的,即使能夠給出,也可能是個相當複雜的函數。爲了客觀地反映一個算法的執行時間,可以用算法中基本語句的執行次數來度量算法的工作量。基本語句是執行次數與整個算法的執行次數成正比的語句,基本語句對算法運行時間的貢獻最大,是算法中最重要的操作。這種衡量效率的方法得出的不是時間量,而是一種增長趨勢的度量。換而言之,只考察問題規模充分大時,算法中基本語句的執行次數在漸近意義下的階,稱作算法的漸近時間複雜度,通常使用大O記號表示。
【定義1-1】若存在兩個正的常數c和n0,對於任意的n>=n0,都有T(n)<=c * f(n),則稱T(n) = O(f(n))(讀作“T(n)是Ofn的”,f(n)即與算法的運行時間函數同一數量級的估算函數)
此定義表明了函數T(n)與f(n)具有相同的增長趨勢,並且T(n)的增長至多趨同於函數f(n)的增長。大O記號用來描述增長率的上限,也就是說,當輸入規模爲n時,算法耗費的時間的最大值。
算法的時間複雜度實際上是一種估算技術,若兩個算法中的一個比另一個“稍微快一點”時,並不能基於時間複雜度來判斷哪個算法更爲優越。但在實際應用中,基於時間複雜度來判斷算法的效率被證明是很有效的,尤其在確定算法是否值得實現的時候。常見的時間複雜度如下:
算法的時間複雜度是衡量一個算法優劣的重要標準。一般而言,具有多項式時間複雜度的算法是可以接受的,可使用的算法,而具有指數時間複雜度的算法,僅當問題規模足夠小的時候纔是可以使用的算法。
算法的空間複雜度
算法在運行過程中所需的存儲空間包括:
- 輸入/輸出數據佔用的空間
- 算法本身佔用的空間
- 執行算法所需要的輔助空間
其中,輸入/輸出數據佔用的空間取決於問題,與算法無關;算法本身佔用的空間雖然與算法相關,但一般其大小是固定的。所以,算法的空間複雜度是指算法在執行過程中需要的輔助空間數量,也就是除算法本身和輸入輸出數據所佔用的空間外,算法臨時開闢出的存儲空間。
如果算法所需的輔助空間相對於問題規模來說是一個常數,我們稱此算法爲原地(或就地)工作,否則,這個輔助空間數量應該是問題規模的函數,通常記作:
其中,n爲問題規模,分析方法與算法的時間複雜度類似。