演算法時間複雜度及效率(二)

來源:互聯網
上載者:User

標籤:bsp   span   情況下   lex   一個   type   比較   ESS   ext   

        今天我們來看下演算法複雜度和效率的問題,在判斷一個演算法的效率時,運算元量中的常數項和其他次要項常常是可以忽略的,只需要關注 最高階項就能得出結論。那麼我們如何用符號定性的判斷演算法的效率呢?演算法的複雜度分為兩部分:1、 時間複雜度,即演算法運行後對時間需求量的定性描述;2、 空間複雜度,即演算法運行後對空間需求量的定性描述。

        資料結構重點關注的是演算法的效率問題,因此,我們後面會集中於討論演算法的時間複雜度;但其使用的方法完全可以用於空間複雜度的判斷!我們經常在進行演算法的時間複雜度用大O標記法來進行分析。下來對此種方法進行說明,演算法效率嚴重依賴於操作(Operation)數量;運算元量的估算可以作為時間複雜度的估算;在判斷時首先關注運算元量的最高次項。如下:

        下來我們來分析下常見的時間複雜度:

        1、線性階時間複雜度:O(n)。如下:

        2、對數階時間複雜度:O(logn)。如下

        3、平方階時間複雜度:O(n2)。如下:

        下來我們來看看常見的時間複雜度,如所示

        常見的時間複雜度的比較,如下

        下面我們通過執行個體來進行分析下,下面的函數程式複雜度是怎樣的

int find(int a[], int n, int v){    int ret = -1;        for(int i=0; i<=n; i++)    {        if( a[i] == v )        {            ret = i;            break;        }    }        return ret;}

        我們如果定義的數組 a[5] = {1, 2, 3, 4, 5}; 如果是 int min = find(a, 5, 1); 這種則是最好情況了,僅需執行 1 次迴圈,此時便是 O(1);如果是 int max = find(a, 5, 5);此時便是最壞的情況了,需要全部執行,此時便是 O(n)。那麼此時演算法的最好與最壞情況便體現出來了,當演算法在最乖情況下仍然能滿足需求時,可以推斷,演算法的最好情況和平均情況都滿足需求。在以後沒有進行特殊說明時,所分析演算法的時間複雜度都是指最壞時間複雜度。

        演算法的空間複雜度(Space Complexity),其定義為 S(n) = S(f(n))。其中 n 為演算法的問題規模,f(n) 為空白間使用函數,與 n 相關。推倒時間複雜度的方法同樣適用於空間複雜度,例如,當演算法所需要的空間是常數時,其空間複雜度為 S(1)。我麼來看看下面這個程式的空間複雜度為多少

long sum1(int n){    long ret = 0;    int* array = new int[n];        for(int i=0; i<n; i++)    {        array[i] = i + 1;    }        for(iunt i=0; i<n; i++)    {        ret += array[i];    }        delete[] array;        return ret;}

        我們看到第一行為 1,第三行的 ret 定義也為 1,指標數組 array 的定義其空間複雜度為 n,下面兩個進行 for 迴圈的空間複雜度分別為 1。因此整個程式所需的單位記憶體為: n + 4;即空間複雜度:S(n+4) = S(n)。那麼時間跟空間之間是否存在某種聯絡呢?在多數情況下,演算法的時間複雜度更令人關注,因為現在的記憶體都很大。如果有必要的話,可以通過增加額外空間降低時間複雜度;同理,也可以增加演算法的耗時降低空間複雜度。下來我們來看個空間換時間的範例程式碼,代碼的背景是在 1-1000 中的某些數字搜組成的數組中,設計一個演算法類找出出現次數最多的數字。

#include <iostream>using namespace std;void sreach(int a[], int len){    int pi[1000] = {0};    int max = 0;        for(int i=0; i<len; i++)    {        pi[a[i] -1]++;    }        for(int i=0; i<1000; i++)    {        if( max < pi[i] )        {            max = pi[i];        }    }        for(int i=0; i<1000; i++)    {        if( max == pi[i] )        {            cout << i + 1 << endl;        }    }}int main(int argc, char* argv[]){    int a[] = {1, 1, 3, 4, 5, 6, 6, 6, 3, 3};        sreach(a, sizeof(a)/sizeof(*a));        return 0;}

        我們來看看列印結果

        我們看到列印了 3 和 6,因為最大數 6 出現了 3 次。那麼此次我們的程式實現中函數的時間複雜度為 O(n)。那麼問題來了,當兩個演算法的大 O 標記法相同時,是否意味著兩個演算法的效率完全相同呢?肯定是不相同的!通過今天對演算法的時間複雜度和效率的學習,總結如下:1、時間複雜度是演算法運行時對於時間的需求量;2、大 O 標記法用於描述演算法的時間複雜度,它只關注運算元量的最高次項;3、常見的時間複雜度為:線性階,平方階和對數階;4、一般而言,在工程中使用的演算法其複雜度都不超過 O(n3);5、演算法分析與設計時,重點考慮最壞情況下的時間複雜度,大 O 標記法用於適用於演算法的空間複雜度;6、空間換時間是工程開發中常用的策略。


         歡迎大家一起來學習資料結構,可以加我QQ:243343083。

演算法時間複雜度及效率(二)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.