首先:借鑒前人大佬!感謝!本文只做整理
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的三次方次 } }
引文中給出了如下的解釋,我覺得受益良多。
時間復雜度不是表示程序解決一個問題所花費的時間,而是表示,當問題規模擴大后,程序需要的時間長度增長有多快。也就是,對於計算機,處理某一個特定數據的效率不能衡量程序的好壞,而應該看這個數據規模擴大到數百倍后程序的運行時間是否一樣?或者是否變慢了?
不管數據多大,程序處理畫的時間始終是那么多的,我們就說這個程序時好的,具有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!)型復雜度,它是非多項式級的,其復雜度計算機往往不能承受。當我們在解決一個問題時,我們選擇的算法通常都需要是多項式級的復雜度,非多項式級的復雜度需要的時間太多,往往會超時,除非是數據規模非常小。
