寫這篇文章源於以前的一次面試以及網上看到各類說原生的sort比快排快的例子,由於他們都沒有寫好快排。面試的時候讓我寫一個快排,我寫出了我在網上看的的很簡潔的一段代碼(後來發現這個代碼在數據結構和算法JavaScript描述這本書上也有):面試
function quickSort(arr){ if(arr.length < 1){ return []; } var left = [],right = [],flag = arr[0]; for(var i=1;i<arr.length;i++){ if(arr[i] <= flag){ left.push(arr[i]); }else{ right.push(arr[i]); } } return quickSort(left).concat(flag,quickSort(right)); }
這樣寫的話,乍一看確實是快排的思想,把比主元小的元素放到左數組,把比主元大的元素放到右數組,而後分別對左右數組的元素進行排序最終拼接成新的數組。
可是計算機課程裏講解快排的時候都不是這樣講解的,一趟快速排序的算法通常是這樣講解的:算法
採用js實現的版本以下:chrome
function quickSort_two(arr){ function sort(start,end){ if(start + 1 > end){ return; } var flag = arr[start],f = start,l = end; while(f < l){ while(f < l && arr[l] > flag){ l--; } arr[f] = arr[l]; while(f < l && arr[f] <= flag){ f++; } arr[l] = arr[f]; } arr[f] = flag; sort(start,f-1); sort(f+1,end); } sort(0,arr.length-1); }
對比這兩中快排的寫法,在時間複雜度上都是O(nlogn),可是第二種寫法使用了更少的空間,第一種寫法的空間複雜度是O(nlogn),而第二種的空間複雜度是O(logn),並且對數組的操做都在原數組上進行,減去了建立空間的消耗和時間,在性能上無疑有了更多的提高。數組
下面是三種排序算法的一個對比:數據結構
function quickSort_one(arr){ if(arr.length < 1){ return []; } var left = [],right = [],flag = arr[0]; for(var i=1;i<arr.length;i++){ if(arr[i] <= flag){ left.push(arr[i]); }else{ right.push(arr[i]); } } return quickSort_one(left).concat(flag,quickSort_one(right)); } function quickSort_two(arr){ function sort(start,end){ if(start + 1 > end){ return; } var flag = arr[start],f = start,l = end; while(f < l){ while(f < l && arr[l] > flag){ l--; } arr[f] = arr[l]; while(f < l && arr[f] <= flag){ f++; } arr[l] = arr[f]; } arr[f] = flag; sort(start,f-1); sort(f+1,end); } sort(0,arr.length-1); } function quickSort_three(arr){ arr.sort(function(a,b){ return a-b; }); } function countTime(fn,arr){ var start = Date.now(); fn(arr); var end = Date.now(); console.log(end - start); } function randomVal(num){ var arr = []; for(var i=0;i<num;i++){ arr.push(Math.ceil(Math.random()*num)); } return arr; }
在chrome下的一個運行狀況(以100000個數爲例,因爲每次排序後數組都發生了改變,因此每次都建立了新數組,以100000的基數來算的話,雖然不是同一個數組,可是結果也是值得參考的):dom
在firefox下的運行結果:數據結構和算法
不管是firefox仍是chrome,第一種排序算法的時間都是最長的,第二種是最快的,原生的sort方法比第二種方法稍微慢一點,但比第一種仍是快多了。性能