1. 程式人生 > >重拾演算法(一):演算法效率分析(空間複雜度和時間複雜度)

重拾演算法(一):演算法效率分析(空間複雜度和時間複雜度)

前言:

演算法效率分析分為兩種:第一種是時間效率,第二種是空間效率。時間效率被稱為時間複雜度,而空間效率被稱作空間複雜度。

時間複雜度主要衡量的是一個演算法的執行速度,而空間複雜度主要衡量一個演算法所需要的額外空間,在計算機發展的早期,計算機的儲存容量很小。所以對空間複雜度很是在乎。但是經過計算機行業的迅速發展,計算機的儲存容量已經達到了很高的程度。所以我們如今已經不需要再關注一個演算法的空間複雜度。

空間複雜度:

程式所需要的空間主要由以下部分構成:
  指令空間。儲存經過編譯之後的程式指令。指令有運算元和操作碼構成。
  資料空間。儲存所有常量和所有變數值所需的空間。
  環境棧空間。儲存函式呼叫返回時恢復執行所需要的信
息。 


(1)指令空間
程式所需指令空間的大小取決於如下因素:
  把程式編譯成機器程式碼的編譯器。所使用的編譯器不同,
則產生的機器程式碼長度就會有所差異。
  編譯時實際採用的編譯器選項。 有些編譯器帶有選項, 如
優化模式、 覆蓋模式等等。 所取的選項不同, 產生的機器
程式碼也會不同。
  目標計算機。 目標計算機的配置也會影響程式碼的規模。 例
如, 如果計算機具有浮點處理硬體, 那麼, 每個浮點操作
可以轉化為一條機器指令。 否則, 必須生成模擬的浮點計
算程式碼,使整個機器程式碼加長。
(2)資料空間
分成兩部分:儲存常量和簡單變數;儲存複合變數。
  儲存常量和簡單變數。 取決於所用的計算機和編譯器, 以
及變數與常量的數目。
  儲存複合變數。 包括資料結構所需的空間及動態分配的空
間。
(3)環境棧空間
呼叫一個函式時,下面資料儲存在環境棧中:
  返回地址。
  所有區域性變數的值、傳值形式引數的引數值。
  所有引用引數的定義。
所以一個程式所需要的空間可分為兩部分:
① 固定部分。獨立於例項特徵,主要包括指令空間、簡單變
量以及定長複合變數佔用的空間、常量佔用的空間。
② 可變部分。 主要包括複合變數所需空間、 動態分配的空間、
遞迴棧所需要的空間。
  複合變數所需的空間依賴於所解決的具體問題。
  動態分配的空間和遞迴棧所需要的空間依賴於例項特徵


例:template <class T> //
int Find( const T a[], int n, const T&x)
{   int i ;
for(i = 0; i<n&& a[i] != x; ++i){}
return(i== n) ? -1: i ;

問題。在a[0..(n-1)]中搜索x,
若找到則回所在的位置,否
則返回-1。
  例項特徵。 採用陣列的長度n
作為例項特徵。
  分析。陣列地址a需要4位元組,引數x需要4位元組,n需要4
位元組,區域性變數i需要4位元組,整數常量-1需要4位元組,總
共需要20位元組,獨立於n,所以 =
Find
( ) 0 S n 。
  注意。陣列a所需要的空間是在其他函式中分配的,不能
算作函式Find所需要的空間。

我們在此說明演算法的時間複雜度的計算方法:
在說明之前,我先講幾個概念:

1.輸入規模:

在大多數的演算法中,對於輸入規模較大的演算法,一般執行需要的時間久更長。例如:對於一組資料進行排序,你輸入 10 個數跟你輸入10000個數的演算法執行時間是不一樣的。所以在研究演算法的效率時,把它作為一個以演算法輸入規模n為引數的函式是非常合乎邏輯的。但是要注意的是,並不是輸入了多少資料,資料規模就是多少。輸入規模是需要進行選取的。比如:對於兩個n*n 的矩陣,你所寫的演算法的輸入規模可以選取為n ,也可以選取為n*n。對於大多數的情況下,選取什麼作為引數都是可以看出來的(經驗有了,水到渠成)。比如:對於排序,查詢等演算法的輸入規模一般都選取它們的輸入資料量n,對於n次多項式來說,它的引數就是多項式的係數。

2.演算法的執行時間度量:

演算法的執行時間,你第一時間看到這個可能會以為演算法的執行時間肯定會以秒,分鐘,甚至小時等時間的標準度來表示。但是這樣的表示方式存在有很大的問題:這種方式很是依賴計算機的執行速度,依賴於演算法程式實現的質量已經你選用的編譯器等等。而且這種方式會導致程式的執行時間難以計算,我們必須用一種不依賴與任何無關因素的度量標準:基本操作。也被稱為演算法中最重要的操作。比如:對兩種排序演算法,我們沒有辦法計算出程式運行了多少時間,但是我們可以根據計算來得到每個程式的基本操作所出現的次數:加減,賦值等等。基本操作可能會有很多種,但是我們只需要找出來貢獻最大的那個就行了。對於數學問題的演算法:最消耗時間的是除法,其次是乘法,最後是加法和減法。

3.增長次數:

就是當n變大時,即輸入規模變大時,對演算法的時間複雜度相關函式的相關影響。



4.演算法的平均.最差.和最優效率:

演算法的最差效率:當輸入規模為n時,演算法在最壞情況下的效率。

演算法的最優效率:當輸入規模為n時,演算法在最優的情況下的效率。

演算法的平均效率:在實際的假設情況下,演算法所可能發生的正推推斷下所具有的效率。一般是通過得到或者是假設各類輸入的概率分佈,以推匯出我們所希望                                 的基本操作次數。

以順序查詢演算法為例:

演算法的最差效率:n個數據,在最後一次判斷才找到。效率為n。

演算法的最優效率:n個數據,第一次就判斷就招到,效率為1

演算法的平均效率:n個數據,我們先假設能招到的概率,然後我們需要求得在第一次查詢招到的概率、第二次查詢招到的概率等等一直求,然後算得總的操作                                  次數。得出演算法的平均效率

演算法時間效率分析框架:

對於輸入規模為n 的演算法,我們可以統計它的基本操作執行次數,對其效率進行度量。

5.漸進符號:









6.基本的漸進效率型別:




圖片用自: