關於時間復雜度~


首先:借鑒前人大佬!感謝!本文只做整理

http://www.matrix67.com/blog/archives/105

 

首先在文中介紹了時間復雜度O,本身自己對於這個有所遺忘,並且本身在算法課上學的不咋地,正好借此梳理一下。

下面給出百度百科關於時間復雜的定義:

在計算機科學中,算法的時間復雜度是一個函數,它定性描述了該算法的運行時間。這是一個關於代表算法輸入值的字符串的長度的函數。時間復雜度常用大O符號表述,不包括這個函數的低階項和首項系數。

百度百科關於時間復雜度的計算方法:

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

分析:隨着模塊n的增大,算法執行的時間的增長率和 f(n) 的增長率成正比,所以 f(n) 越小,算法的時間復雜度越低,算法的效率越高。

2. 在計算時間復雜度的時候,先找出算法的基本操作,然后根據相應的各語句確定它的執行次數,再找出 T(n) 的同數量級(它的同數量級有以下:1,log2n,n,n log2n ,n的平方,n的三次方,2的n次方,n!),找出后,f(n) = 該數量級,若 T(n)/f(n) 求極限可得到一常數c,則時間復雜度T(n) = O(f(n))

例:算法:

for(i=1; i<=n; ++i)
{
    for(j=1; j<=n; ++j)
    {
        c[i][j] = 0;//該步驟屬於基本操作執行次數:n的平方次
        for(k=1; k<=n; ++k)
            c[i][j] += a[i][k] * b[k][j];//該步驟屬於基本操作執行次數:n的三次方次
    }
}
 
則有    ,根據上面括號里的同數量級,我們可以確定 n的三次方 為T(n)的同數量級則有
   
,然后根據 T(n)/f(n) 求極限可得到常數c則該算法的時間復雜度:T(n) = O(n^3) 注:n^3即是n的3次方。
3.在pascal中比較容易理解,容易計算的方法是:看看有幾重for循環,只有一重則時間復雜度為O(n),二重則為O(n^2),依此類推,如果有二分則為O(logn),二分例如快速冪、二分查找,如果一個for循環套一個二分,那么時間復雜度則為O(nlogn)。

引文中給出了如下的解釋,我覺得受益良多。

時間復雜度不是表示程序解決一個問題所花費的時間,而是表示,當問題規模擴大后,程序需要的時間長度增長有多快。也就是,對於計算機,處理某一個特定數據的效率不能衡量程序的好壞,而應該看這個數據規模擴大到數百倍后程序的運行時間是否一樣?或者是否變慢了?

不管數據多大,程序處理畫的時間始終是那么多的,我們就說這個程序時好的,具有O(1)的時間復雜度,稱常數級復雜度。數據規模變得多大,花的時間變得多長,這個程序的復雜度就是O(n),比如找N個數中最大的;而像冒泡排序、插入排序等,數據擴大2倍,時間變慢4倍的,屬於O(n^2)的復雜度。還有一些窮舉類的算法,所需時間長度成幾何階數上漲,這就是O(a^n)的指數級復雜度,甚至O(n!)的階乘級復雜度。不會存在O(2*n^2)的復雜度,因為前面的那個“2”是系數,根本不會影響到整個程序的時間增長。同樣地,O (n^3+n^2)的復雜度也就是O(n^3)的復雜度。因此,我們會說,一個O(0.01*n^3)的程序的效率比O(100*n^2)的效率低,盡管在n很小的時候,前者優於后者,但后者時間隨數據規模增長得慢,最終O(n^3)的復雜度將遠遠超過O(n^2)。我們也說,O(n^100)的復雜度小於O(1.01^n)的復雜度。

容易看出,前面的幾類復雜度被分為兩種級別,其中后者的復雜度無論如何都遠遠大於前者:一種是O(1),O(log(n)),O(n^a)等,我們把它叫做多項式級的復雜度,因為它的規模n出現在底數的位置;另一種是O(a^n)和O(n!)型復雜度,它是非多項式級的,其復雜度計算機往往不能承受。當我們在解決一個問題時,我們選擇的算法通常都需要是多項式級的復雜度,非多項式級的復雜度需要的時間太多,往往會超時,除非是數據規模非常小。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM