1. 程式人生 > >演算法分析(時間複雜度和空間複雜度)

演算法分析(時間複雜度和空間複雜度)

演算法分析(時間複雜度和空間複雜度)
對於一個給定的演算法需要做兩項分析,第一就是證明演算法的正確性,第二就是計算演算法的複雜度。演算法的複雜度包括時間複雜度和空間複雜度。

1  度量演算法效率的方法
共存在兩種方法:事後統計法和事前分析估計演算法。

事後統計法:先將演算法實現,然後輸入適當的資料執行,計算演算法的時間複雜度和空間複雜度。

事前分析估演算法(漸進複雜度):對演算法所消耗資源的一種估算方法。比較常用。

本文主要是漸進複雜度的解釋。

2  演算法的時間複雜度
影響演算法時間複雜度的主要因素是問題規模。

問題規模:是指輸入量的多少。規模大的輸入量需要的執行時間更長。所以執行演算法所需要的時間T的問題是問題規模n的函式,記作T(n)。

為了客觀的表示一個演算法的執行時間,可以用基本語句的執行次數來度量演算法的工作量。

定義:一般情況下,演算法中基本操作重複執行的次數是問題規模n的某個函式,用T(n)表示,若有某個輔助函式f(n),使得當n趨近於無窮大時,T(n)/f(n)的極限值為不等於零的常數,則稱f(n)是T(n)的同數量級函式。記作T(n)=O(f(n)),稱O(f(n)) 為演算法的漸進時間複雜度,簡稱時間複雜度。

通常採用大O記號表示。

時間複雜度分析的基本策略是:從內向外分析,從最深層開始分析。如果遇到函式呼叫,要深入函式進行分析。

3  求解時間複雜度的步驟
(1)找出演算法的基本語句,一般是迴圈體。

(2)計算基本語句執行次數的數量級,也就是基本語句執行次數函式的最高次冪。可忽略低次冪和係數。

(3)用大O記號表示時間複雜度。

4  計算時間複雜度常用性質
(1)一些簡單的輸入輸出賦值語句,近似為O(1)。

(2)對於順序結構需要求和法則。

求和法則:若T1(n)=O(f(n))、 T2(n)=O(g(n)),則 T1(n)+T2(n)=O(max(f(n), g(n)))。

(3)對於選擇結構(if判斷),需要看執行語句。

(4)對於迴圈結構採用乘法法則。

乘法法則:若T1(n)=O(f(n))、 T2(n)=O(g(n)),則 T1*T2=O(f(n)*g(n))。

如果演算法中包含巢狀的迴圈,則基本語句通常是最內層的迴圈體,如果演算法中包含並列的迴圈,則將並列迴圈的時間複雜度相加。

5  常用時間複雜度示例
常見的時間複雜度有:常數階O(1),對數階O(log2n),線性階O(n), 線性對數階O(nlog2n),平方階O(n2),立方階O(n3)。由小到大依次為:Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<Ο(n3)<Ο(2n)<Ο(n!)。

(1)Ο(log2n)(二分查表)

decimal Factorial(int n)
 
    {
 
      if (n == 0)
 
        return 1;
 
      else
 
        return n * Factorial(n - 1);
 
}


(2)O(n)(一次for迴圈)

decimal Factorial(int n)
 
    {
 
      if (n == 0)
 
        return 1;
 
      else
 
        return n * Factorial(n - 1);
 
}


(3)Ο(nlog2n)(快排)

void quickSort(int arr[], int left, int right)  
{  
    if (left < right)  
    {  
        int key = arr[left];    
        int i = left, j = right;  
        while (i < j)  
        {  
            while (arr[j] > key && j > i) 
                j--;  
            if (i < j)     
                arr[i++] = arr[j];  
            while (arr[i] < key && i < j)  
                i++;  
            if (i < j)  
                arr[j--] = arr[i];  
        }  
        arr[i] = key;  
        quickSort(arr, left, i - 1);  
        quickSort(arr, i + 1, right);  
    }  
}  


(4)O(n2)(氣泡排序)

void BubbleSort(int arr[],int num)
{
    int i,j;
    int temp=0;
    for(i=0;i<num-1;i++)
    {
        for(j=0;j<num-i-1;j++)
        {
            if(arr[j]>arr[j+1])
            {
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}


6  演算法的空間複雜度

空間複雜度定義了為演算法所消耗的儲存空間。是演算法執行是所佔用儲存空間大小的量度。