算法複雜度是咱們來衡量一個算法執行效率的一個度量標準,算法複雜度一般主要有時間複雜度和空間複雜度兩種。時間複雜度就是指算法代碼在運行最終獲得咱們想要的結果時所消耗的時間,而空間複雜度則是指算法中用來存儲的數據結構所佔用的空間。每每一個時間複雜度比較低的算法擁有着較高的空間複雜度,二者是互相影響的,咱們前面講解數據結構中的一些例子和代碼也足以說明這一點。本文會簡單介紹一下用於描述算法的性能和複雜程度的大O表示法。javascript
咱們先來看一段簡單的代碼,來幫助咱們理解什麼是大O表示法:html
function increment(num) { return ++num; } console.log(increment(1));
上面的代碼聲明瞭一個函數,而後調用它。這樣的代碼不管咱們傳入的參數是什麼,它都會返回自增後的結果。也就是說該函數的執行時間跟咱們傳入的參數沒有任何關係,執行的時間都是X。所以,咱們稱該函數的複雜度是O(1),常數的。java
咱們再來看看前面講過的順序搜索算法,咱們直接把代碼拿過來用就行了。算法
//順序搜索 function sequentialSearch(array,item) { for(var i = 0; i < array.length; i++) { if(item === array[i]) { return i; }; }; return -1; };
如今咱們假設要搜索的數組是[1,2,3...9,10],而後咱們搜索1這個元素,那麼在第一次判斷時就能找到想要搜索的元素。那麼咱們這裏先假設每執行一次循環的開銷是1。那麼咱們還想搜索11,數組中沒有這個元素,sequentialSearch 就會執行十次遍歷整個數組,發現沒有後返回-1。那麼在最壞的狀況下,數組的長度大小決定了算法的搜索時間。這樣的函數的時間複雜度就是O(n),線性的,這裏的n就是數組的長度。api
那麼,咱們來稍微修改一下sequentialSearch讓它能夠計算開銷:數組
//順序搜索 function sequentialSearch(array,item) { var cost = 0; for(var i = 0; i < array.length; i++) { cost++; if(item === array[i]) { return i; }; }; console.log(array.length,cost); return -1; }; sequentialSearch([1,2,3,4,5,6,7,8,9,10],11);
很簡單,就是加上了一個cost變量來計數。那麼咱們下面再來看看冒泡排序的時間複雜度是怎樣的,這裏咱們再也不浪費篇幅,直接在代碼中加入計數器:數據結構
function swap(array,index1,index2) { var aux = array[index1]; array[index1] = array[index2]; array[index2] = aux; } function bubbleSort(array) { var length = array.length; var cost = 0; for (var i = 0; i < length; i++) { cost++; for (var j = 0; j < length - 1; j++) { cost++; if(array[j] > array[j + 1]) { swap(array,j,j+1); } } } console.log(length,cost); } bubbleSort([2,3,4,1,8,7,9,10]);
代碼自己沒什麼好說的,咱們發現,若是數組的長度是8,那麼咱們排序所消耗的時間就是64,若是長度是10,消耗的時間就是100。換句話說,冒泡排序的時間複雜度就是數組長度的平方,也就是O(n2)。數據結構和算法
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <style> body { background-color: #DDDDDD; font: 30px sans-serif; } </style> <script type="text/javascript" src="https://www.google.com/jsapi"></script> <script type="text/javascript"> google.load('visualization', '1.0', {'packages':['corechart']}); google.setOnLoadCallback(drawChart); function drawChart() { var data = new google.visualization.DataTable(); data.addColumn('string', 'n'); data.addColumn('number', 'O(1)'); data.addColumn('number', 'O(log n)'); data.addColumn('number', 'O(n)'); data.addColumn('number', 'O(n log n)'); data.addColumn('number', 'O(n^2)'); data.addColumn('number', 'O(2^n)'); for (var i = 0; i <= 30; i++) { data.addRow([i+'', 1, Math.log(i), i, Math.log(i)*i, Math.pow(i,2), Math.pow(2,i)]); } var options = {'title':'Big O Notation Complexity Chart', 'width':700, 'height':600, 'backgroundColor':{stroke:'#CCC',strokeWidth:1}, 'curveType':'function', 'hAxis':{ title:'Elements (n)', showTextEvery:5 }, 'vAxis':{ title:'Operations', viewWindowMode:'explicit', viewWindow:{min:0,max:450} } }; var chart = new google.visualization.LineChart(document.getElementById('chart_div')); chart.draw(data, options); } </script> </head> <body> <div id='chart_div'></div> </body> </html>
上面的代碼是用js畫的一幅圖,其中有一些經常使用的大O表示法所對應的時間複雜度,你們能夠把代碼COPY到本地自行去看一下,這樣會纔會對大O表示法有更好的理解,爲了偷點懶,也爲了你們能夠確實的本身去看一下圖標。我這裏不會把圖給你們貼上的。函數
下面給你們貼上幾張圖,來看看咱們以前學習的一些數據結構和算法的時間複雜度是怎樣的。性能
一、經常使用數據結構的時間複雜度
二、圖的時間複雜度
表格中的V表明頂點,E表明邊。
三、排序算法
四、搜索算法的時間複雜度
終於,咱們瞭解了幾乎咱們前面學過的全部的數據結構和算法的時間複雜度,這樣咱們在選擇算法的時候能夠更確切地評估它的效率。
那麼,咱們本系列的文章也將告一段落。後面準備深刻的學習一下CSS。可能會把其中一些比較有意思的地方貼出來與你們分享。
最後,因爲本人水平有限,能力與大神仍相差甚遠,如有錯誤或不明之處,還望你們不吝賜教指正。很是感謝!
最後,感謝你們的閱讀。若是您以爲或許還有那麼點用處,能夠把個人主頁加入你的收藏夾中以便須要的時候能夠快速的找到。