演算法的時間複雜度和空間複雜度 博客說明 文章所涉及的資料來自互聯網整理和個人總結,意在於個人學習和經驗彙總,如有什麼地方侵權,請聯繫本人刪除,謝謝! 演算法的時間複雜度 時間頻度 一個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數多,它花費時間就多。一個演算法中的語句執行次數稱為語 ...
演算法的時間複雜度和空間複雜度
博客說明
文章所涉及的資料來自互聯網整理和個人總結,意在於個人學習和經驗彙總,如有什麼地方侵權,請聯繫本人刪除,謝謝!
演算法的時間複雜度
時間頻度
一個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數多,它花費時間就多。一個演算法中的語句執行次數稱為語句頻度或時間頻度。
時間複雜度
一般情況下,演算法中的基本操作語句的重覆執行次數是問題規模n的某個函數,用T(n)表示,若有某個輔助函數f(n),使得當n趨近於無窮大時,T(n) / f(n) 的極限值為不等於零的常數,則稱f(n)是T(n)的同數量級函數。記作 T(n)=O( f(n) ),稱O( f(n) ) 為演算法的漸進時間複雜度,簡稱時間複雜度。
計算時間複雜度的方法
- 用常數1代替運行時間中的所有加法常數
- 修改後的運行次數函數中,只保留最高階項
- 去除最高階項的繫數
常見的時間複雜度
常數階O(1)
無論代碼執行了多少行,只要是沒有迴圈等複雜結構,那這個代碼的時間複雜度就都是O(1)
int i = 1;
int j = 2;
i++;
j++;
上述代碼在執行的時候,它消耗的時候並不隨著某個變數的增長而增長,那麼無論這類代碼有多長,即使有幾萬幾十萬行,都可以用O(1)來表示它的時間複雜度。
對數階O(log2n)
int i = 1;
while(i<n){
i = i * 2;
}
在while迴圈裡面,每次都將 i 乘以 2,乘完之後,i 距離 n 就越來越近了。假設迴圈x次之後,i 就大於 2 了,此時這個迴圈就退出了,也就是說 2 的 x 次方等於 n,那麼 x = log2n也就是說當迴圈 log2n 次以後,這個代碼就結束了。因此這個代碼的時間複雜度為:O(log2n) 。 O(log2n) 的這個2 時間上是根據代碼變化的,i = i * 3 ,則是 O(log3n)
線性階O(n)
for(i = 1; i <= n; i++){
j = i;
}
這段代碼,for迴圈裡面的代碼會執行n遍,因此它消耗的時間是隨著n的變化而變化的,因此這類代碼都可以用O(n)來表示它的時間複雜度
線性對數階O(nlog2n)
for(m =1;m<n;m++){
i = 1;
while(i<n){
i = i * 2;
}
}
線性對數階O(nlogN) 其實非常容易理解,將時間複雜度為O(logn)的代碼迴圈N遍的話,那麼它的時間複雜度就是 n * O(logN),也就是了O(nlogN)
平方階O(n^2)
for(j=1;j<n;j++){
for(i=1;i<n;i++){
m = j+i;
}
}
平方階O(n²) 就更容易理解了,如果把 O(n) 的代碼再嵌套迴圈一遍,它的時間複雜度就是 O(n²),這段代碼其實就是嵌套了2層n迴圈,它的時間複雜度就是 O(nn),即 O(n²) 如果將其中一層迴圈的n改成m,那它的時間複雜度就變成了 O(mn)
立方階O(n^3)
三層迴圈
k次方階O(n^k)
k層迴圈
指數階O(2^n)
常見的演算法時間複雜度大小
由小到大依次為:Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<Ο(n3)< Ο(nk) <Ο(2n) ,隨著問題規模n的不斷增大,上述時間複雜度不斷增大,演算法的執行效率越低
從圖中可見,
建議
儘可能避免使用指數階的演算法
平均時間複雜度和最壞時間複雜度
- 平均時間複雜度是指所有可能的輸入實例均以等概率出現的情況下,該演算法的運行時間。
- 最壞情況下的時間複雜度稱最壞時間複雜度。一般討論的時間複雜度均是最壞情況下的時間複雜度。 這樣做的原因是:最壞情況下的時間複雜度是演算法在任何輸入實例上運行時間的界限,這就保證了演算法的運行時間不會比最壞情況更長。
- 平均時間複雜度和最壞時間複雜度是否一致,和演算法有關
演算法的空間複雜度
- 類似於時間複雜度的討論,一個演算法的空間複雜度(Space Complexity)定義為該演算法所耗費的存儲空間,它也是問題規模n的函數。
- 空間複雜度(Space Complexity)是對一個演算法在運行過程中臨時占用存儲空間大小的量度。有的演算法需要占用的臨時工作單元數與解決問題的規模n有關,它隨著n的增大而增大,當n較大時,將占用較多的存儲單元,例如快速排序和歸併排序演算法就屬於這種情況
- 在做演算法分析時,主要討論的是時間複雜度。從用戶使用體驗上看,更看重的程式執行的速度。一些緩存產品(redis, memcache)和演算法(基數排序)本質就是用空間換時間.
感謝
尚矽谷
萬能的網路
以及勤勞的自己
關註公眾號: 歸子莫,獲取更多的資料,還有更長的學習計劃