執行算法所需的計算工做量。通常來講,計算機算法是問題規模n
的函數f(n)
,算法的時間複雜度也所以記作T(n)=O(f(n))
;
常見時間複雜度有:常數階、線性階、平方階、立方階、對數階、nlog2n
階、指數階
效率:O(1) > O(log2n)> o(n)> o(nlog2n) > o(n^2) > o(n^3) > o(2^n) > o(n!) > o(n^n)
舉例:計算1+2+3+....+n的和 $sum=0 for($i=1;$i<=$n;$i++){ $sum+=$i }
能夠看到循環了n
次,因此時間複雜度就是O(n)
, 時間複雜度就是程序計算次數
算法
1.用常數1
來取代全部時間中的全部加法常數函數
好比上面的例子中,無論n爲多少,計算次數都是3,那麼時間複雜度爲O(1)
,而不是O(3)
2.在修改後的運行次數函數中,只保留最高階項spa
好比運算的次數爲n^2+1
,那麼爲時間複雜度爲o(n^2)
3.若是最高階存在且不是1
,則去除與這個項相乘的常數.net
2n^2+3n+1 ->n^2
爲何會去掉這些值,看下圖code
當計算量隨着次數原來越大的時候,n
和1
的區別不是太大,而n^2
曲線變得愈來愈大,因此這也是2n^2+3n+1 ->n^2
最後會估量成n^2
的緣由,由於3n+1
隨着計算次數變大,基本能夠忽略不計,其餘都相似blog
O(1)
function test($n){ echo $n; echo $n; echo $n; }
無論$n
是多少,只運行3次,那麼時間複雜度就是O(3)
,取爲O(1)
排序
O(n)
for($i=1;$i<=$n;$i++){ $sum+=$i }
o(n^2)/o(n^3)
$sum=0; for($i=1;$i<=$n;$i++){ for($j=1;$j<$n;$j++){ $sum+=$j } }
兩次循環,裏面循環執行了n
次,外層循環也執行了n
次,因此時間複雜度爲O(n^2)
,立方階同樣
O(n^2/2+n/2)->O(n^2)
for(){ for(){ ..... ----------->n^2 } } + for(){ ------------> n } + echo $a+$b --------------> 1
因此總體上計算次數爲n^2+n+1
,咱們算時間複雜度爲O(n^2)
O(log2n)
while($n>=1){ $n=$n/2; } n 執行次數 1 1 2 2 3 2 規律: 第一次 第二次 第三次 第四次 第五次 20--------->10---------->5-------->2.5------->1 n n/2 n/2/2 n/2/2/2 n/2/2/...
全部規律:n/(2^m)=1
;咱們須要算出m
, 轉換成n=2^m
,得出m=log2n
,因此時間複雜度爲O(logn)
或者O(log2n)
內存
算法須要消耗的內存空間。即爲S(n)=O(f(n))
;包括程序代碼所佔用的空間,輸入數據所佔用的空間和輔助變量所佔用的空間這三個方面。計算和表達方式與時間複雜度相似,通常用複雜度的漸近性來表示rem
關於O(1)
的問題,O(1)
是說數據規模和臨時變量數目無關,並非說僅僅定義一個臨時變量。舉例:不管數據規模多大,我都定義100個變量,這就叫作數據規模和臨時變量數目無關。就是說空間複雜度是O(1)
。
舉例:冒泡排序的元素交換,空間複雜度O(1)
冒泡排序就是兩兩交換,中間設置臨時變量存儲交換的值,無論要交換的數據多大,臨時變量始終爲固定數量
冒泡排序:把$arr=[1,3,2,4,6,5]排序出來 原理:兩兩相鄰的數進行比較,若是反序就交換,不然不交換 1 3 2 4 6 5 首先1和3比較,不動 1 3 2 4 6 5 再次3和2比較,交換 1 2 3 4 6 5 再次3和4比較,不動 1 2 3 4 6 5 再次4和6比較,不動 1 2 3 4 6 5 再次6和5比較,交換 1 2 3 4 5 6 for($i=0;$i<=$n;$i++){ for($j=0;$j<=$n;$j++){ if($arr[$j]>$arr[$j+1]){ $tmp=$arr[$j]; $arr[$j]=$arr[$j+1]; $arr[$j+1]=$tmp; } } }
因此時間複雜度爲O(n^2)
,空間複雜度爲O(1)
get
冒泡排序、直接插入排序、希爾排序、選擇排序、快速排序、對排序、歸併排序
二分查找、順序查找