一個演算法花費的時間與演算法中語句執行次數成正比,哪個演算法中語句執行次數多,它花費的時間就多。一個演算法中語句的執行次數稱為語句頻度或時間頻度。記為T(n).
//比如計算1到100所有數字之和,我們設計倆種演算法: int count = 0; int end = 100; //該演算法中使用了for迴圈,迴圈了100+1(最後一次判斷), 時間頻度為T(100)=100+1, 即T(n)=n+1 for(int i=1; i<=end; i++){ count+=i; } //而如果我們使用公式來計算,只需執行一次即可得到結果,時間頻度為T(100)=1, 即T(n)=1 count = (1+end)*end/2
時間複雜度
在電腦科學中,時間複雜性,又稱時間複雜度,演算法的時間複雜度是一個函式,它定性描述該演算法的執行時間。這是一個代表演算法輸入值的字串的長度的函式。時間複雜度常用大O符號表述,不包括這個函式的低階項和首項係數。使用這種方式時,時間複雜度可被稱為是漸近的,亦即考察輸入值大小趨近無窮時的情況。
大O符號
大O符號(Big O notation)是用於描述函式漸進行為的數學符號。更確切地說,它是用另一個(通常更簡單的)函式來描述一個函式數量級的漸近上界。在數學中,它一般用來刻畫被截斷的無窮級數尤其是漸近級數的剩餘項;在電腦科學中,它在分析演算法複雜性的方面非常有用。
常數項可忽略
如下圖, 2n+20和2n 、 3n+10和3n ,隨著n值的增大,執行曲線無限接近,這時我們基本可忽略掉常數項:20、10
低次項可忽略
如下圖,2n^2+3n+10和2n^2、n^2+5n+20和n^2,隨著n值的增大,執行曲線無限接近,這時我們基本可以忽略掉低次項和常數項:3n+10、5n+20
係數可忽略
如下圖, 3n^2+2n和5n^2+7n 隨著n值的增大,執行曲線無限接近,這時我們基本可以忽略掉低次項:2n、5n,和係數:3、5
但是要注意的是,如果n的指數大於2時,它們的係數會對結果影響較大,如下圖的 n^3+5n和6^3+4n,這種情況則不可以忽略係數
所以我們可以把時間頻度T(n)=2n^2+3n+10忽略掉常數、低次項和係數,記成時間複雜度O(n^2)
常見的時間複雜度
-
常數階O(1)
//無論程式碼執行了多少行,引數有多大,只要執行次數沒有隨著輸入引數的變化而變化,那它的時間複雜度就是 O(1) int i = 1; int j = 2; ++i; j++; int m = i+j;
-
對數階O(log2n)
//在while迴圈中,每迴圈一次i都會乘於2,當乘到x次時,i>n則退出迴圈,,所以while內的程式碼會執行x次,即i^x>n,又因為i每次的乘數是2即底數為2,所以它的時間複雜度是 (log2n), 如果乘數是3則是O(log3n) int i = 1; while(i<n){ i = i * 2; }
-
線性階O(n)
//在for迴圈中,j=i會被執行n次,所以它的時間複雜度為O(n) int j = 0; for(int i=1; i<=n; i++){ j = i; }
-
線性對數階O(nlog2n)
//線性對數對數階則是將對數階的程式碼再迴圈執行n遍,如果i的乘數為2,則時間複雜度為O(nlog2n) for(int m=1; m<=n; m++){ int i = 1; while(i<n){ i = i * 2; } }
-
平方階O(n^2)
//平方階則是將線性階再迴圈執行n遍,記總共執行了n*n=n^2,所以它的時間複雜度為O(n^2) int num = 0; for(int i=1; i<=n; i++){ for(int j=1; j<=n; j++){ num = i+j; } }
-
立方階O(n^3)
-
k次方階O(n^k)
//立方階和k次方階參考平方階,原理是一樣的
-
指數階O(2^n)
//因為時間複雜度為0(2^n)的演算法開銷過大,不推薦使用時間複雜度為0(2^n)的演算法
平均時間複雜度和最壞時間複雜度
-
平均時間複雜度是指所有可能的輸入例項均以等概率出現的情況下,該演算法的執行時間。
-
最壞情況下的時間複雜度稱最壞時間複雜度。一般討論的時間複雜度均是最壞情況下的時間複雜度。 這樣做的原因是:最壞情況下的時間複雜度是演算法在任何輸入例項上執行時間的界限,這就保證了演算法的執行時間不會比最壞情況更長。
-
平均時間複雜度和最壞時間複雜度是否一致,和算 法有關(如圖,以排序演算法為例)。
空間複雜度
-
類似於時間複雜度的討論,一個演算法的空間複雜度(Space Complexity)定義為該演算法所耗費的儲存空間,它也是問題規模n的函式。
-
空間複雜度(Space Complexity)是對一個演算法在執行過程中臨時佔用儲存空間大小的量度。有的演算法需要佔用的臨時工作單元數與解決問題的規模n有關,它隨著n的增大而增大,當n較大時,將佔用較多的儲存單元,例如快速排序和歸併排序演算法就屬於這種情況
-
在做演算法分析時,主要討論的是時間複雜度。從使用者使用體驗上看,更看重的程式執行的速度。一些快取產品(redis, memcache)和演算法(基數排序)本質就是用空間換時間.
翻譯 朗讀 複製 正在查詢,請稍候…… 重試 朗讀 複製 複製 朗讀 複製 via 谷歌翻譯(國內)譯