1. 程式人生 > >學習筆錄【演算法效率分析】

學習筆錄【演算法效率分析】

注意:本文摘自《資料結構——從概念到C實現》【王紅梅 皮德常 編著】

目錄

文章目錄



演算法效率分析

度量演算法的效率有兩種方法

一,事後統計,先實現演算法,再輸入資料來測量其時間,空間開銷。此種方法的缺點至少有

  1. 編寫程式實現演算法很耗費時間精力
  2. 實驗結果依賴於計算機的軟硬體等環境因素,有時很容易掩蓋演算法本身的優劣。

二,事前分析估計,漸進複雜度估算,這是對演算法所消耗資源的一種估算方法。



演算法的時間複雜度

    同一個演算法用不同的程式設計語言實現,或者用不同的編譯程式進行編譯,或者在不同的計算機上執行,效率均不相同。撇開與計算機軟硬體有關的因素,影響演算法時間代價的最主要因素是問題規模。問題規模是指輸入量的多少,一般來說,它可以從問題的描述中得到。例如,找出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時,演算法耗費的時間的最大值。

​    演算法的時間複雜度實際上是一種估算技術,若兩個演算法中的一個比另一個“稍微快一點”時,並不能基於時間複雜度來判斷哪個演算法更為優越。但在實際應用中,基於時間複雜度來判斷演算法的效率被證明是很有效的,尤其在確定演算法是否值得實現的時候。常見的時間複雜度如下:
O ( log 2 n ) &lt; O ( n ) &lt; O ( n l o g 2 n ) &lt; O ( n 2 ) &lt; O ( n 3 ) &lt; . . . &lt; O ( 2 n ) &lt; O ( n ! ) O(\log_2n)&lt;O(n)&lt;O(nlog_2n)&lt;O(n^2)&lt;O(n^3)&lt;...&lt;O(2^n)&lt;O(n!)
​    演算法的時間複雜度是衡量一個演算法優劣的重要標準。一般而言,具有多項式時間複雜度的演算法是可以接受的,可使用的演算法,而具有指數時間複雜度的演算法,僅當問題規模足夠小的時候才是可以使用的演算法。



演算法的空間複雜度

演算法在執行過程中所需的儲存空間包括:

  1. 輸入/輸出資料佔用的空間
  2. 演算法本身佔用的空間
  3. 執行演算法所需要的輔助空間

    其中,輸入/輸出資料佔用的空間取決於問題,與演算法無關;演算法本身佔用的空間雖然與演算法相關,但一般其大小是固定的。所以,演算法的空間複雜度是指演算法在執行過程中需要的輔助空間數量,也就是除演算法本身和輸入輸出資料所佔用的空間外,演算法臨時開闢出的儲存空間。

    如果演算法所需的輔助空間相對於問題規模來說是一個常數,我們稱此演算法為原地(或就地)工作,否則,這個輔助空間數量應該是問題規模的函式,通常記作:
S ( n ) = O ( f ( n ) ) S(n) = O(f(n))
    其中,n為問題規模,分析方法與演算法的時間複雜度類似。