受大學室友的鼓動,我也打算利用公衆平臺來記錄本身的前端知識積累,同時呢,本身總結的東西,總歸會有侷限性,但願小夥伴能給我指點迷津。知識就是一張巨大的網,做爲一名摸不清頭緒的入學者,惟一能作的事情就是吐好每一根絲,絲擰成線,線再織成網。好啦,開機儀式over,廢話很少說了啦...html
關於Sort()這個函數,決定研究它是由於在看阮老師的箭頭函數時,最後有一個小練習:
請使用箭頭函數簡化排序時傳入的函數:前端
var arr = [10, 20, 1, 2]; arr.sort((x, y) => { ??? }); console.log(arr); // [1, 2, 10, 20]
由於以前js基礎也不紮實,沒有get到這個題的核心,想了想寫了寫,最後放棄了,看了評論裏的答案。個人天,就一句——return x - y;
,當時我就以爲這個函數太神奇了,這麼簡單的解決了數組排序。(上大學那會,懶惰致死的我全部排序算法原理都明明白白,可是歷來沒有寫過,因而就...後悔莫及阿)算法
瞭解原理先從函數定義入手,因而乎...從W3C上搬了一段解釋:數組
定義和用法: sort() 方法用於對數組的元素進行排序。數據結構
語法: arrayObject.sort(sortby)函數
返回值: 對數組的引用。請注意,數組在原數組上進行排序,不生成副本。編碼
說明:code
怎麼查看sort()方法是若是實現排序的呢?此處參考了前輩的文章《sort排序到底怎麼排序》。由於我就特別傻,斷點打到sort()函數這一行,而後step-into執行,不斷在console裏打印arr。。。傻的一p
前輩以下實現的:咱們能夠在比較函數裏把a,b及數組輸出一下,看看是否可以看出使用的排序算法。htm
var arr=[1, 8, 3, 5, -1]; function compare(a,b){ console.log(a,b,arr); return a-b; } arr.sort(compare);
控制檯輸出
1 8 [1, 8, 3, 5, -1]
8 3 [1, 8, 3, 5, -1]
1 3 [1, 8, 8, 5, -1]
8 5 [1, 3, 8, 5, -1]
3 5 [1, 3, 8, 8, -1]
8 -1 [1, 3, 5, 8, -1]
5 -1 [1, 3, 5, 8, 8]
3 -1 [1, 3, 5, 5, 8]
1 -1 [1, 3, 3, 5, 8]
[-1,1, 3, 5, 8]
*/
第一次1和8比較,1<8,不須要調整位置。 blog
第二次8和3比較,8>3,須要調整位置。可是這裏沒有交換位置,僅僅是8覆蓋了3位置。這裏就能夠推斷出不是單純的使用了冒泡算法。
第三是1和3比較,1<3,3替換了8的位置。什麼鬼,幾個意思???看到這裏我也是表示不懂呀。那就繼續往下看咯。
第四是8和5比較,8>5,又僅僅是覆蓋,沒有交換位置。仍是不懂,繼續往下!
第五是3和5比較,3<5,5替換了8的位置,不懂,繼續往下!
第六是8和-1比較,8>-1, 還僅僅是覆蓋,繼續往下!
第7、8、九次,-1依次和5,3,1作了比較,而且5,3,1都移動了一次位置。
咱們得出告終論:sort()方法是使用的冒泡和插入兩種方式結合進行排序的。
這裏我用本身的話總結一下:
冒泡排序:
function bubbel(arr) { var len=arr.length; for(var i=0; i<len; i++) { for(var j=0; j<len; j++) { if(arr[j] > arr[j+1]) { var temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } return arr; }
插入排序:
1.第一輪:將第一個元素當作只有一個元素的有序數組,拿第二個元素和它比較,比它小就插到它前面,比它大就插到它後面。
2.第二輪:通過第一輪,前兩個元素已爲有序數組。再拿第三個元素和前兩個元素比較,看插在哪合適。以此類推。通常會新建一個數組記錄排序後的數組。
// 插入排序 從下標1開始每增1項排序一次,越日後遍歷次數越多 function sort1(array) { var len = array.length, i, j, tmp, result; // 設置數組副本 result = array.slice(0); for(i=1; i < len; i++){ tmp = result[i]; j = i - 1; while(j>=0 && tmp < result[j]){ result[j+1] = result[j]; j--; } result[j+1] = tmp; } return result; }
前面鋪墊了這麼多,終於到了今天的重點——冒泡排序和插入排序是如何混合使用的?即sort()實現的原理。先上個人代碼!! 時隔多年,我終於再也不懶惰,勇敢寫出個人代碼。但願努力不要太晚~
var arr = [1, 8, 3, 5, -1]; var len = arr.length; function compareSet(temp, compare_i){ for(var i = compare_i; i > 0; i--){ if(temp > arr[i-1]){ arr[i] = temp; break; } else{ arr[i] = arr[i-1]; arr[i-1] = temp; } } } for(var i = 0; i < len; i++){ if(arr[i] > arr[i+1]){ var temp = arr[i+1]; arr[i+1] = arr[i]; console.log(arr); compareSet(temp, i); } } console.log(arr);
根據以前分析sort()排序控制檯輸出,先是像冒泡排序那樣相鄰的元素比較。可是,一旦出現須要換位置的操做時,再也不是像插入排序那樣直接交換。而是先用變量temp暫存arr[i+1],再將較大的arr[i]移到[i+1]位置上,對暫存變量temp使用插入排序,將其插入前0 ~ [i-1]有序數組中。把這個temp安排好,再繼續以前的冒泡排序。
**冒泡排序是元素對調後這一輪就無論事了,要重複i-1輪冒泡。
插入排序是無論現有元素的順序是否正確,都給你在已有序數組從頭比較到尾。**
因此,混合起來666。
這裏還有一個前輩寫的sort()實現,我對比一下,個人運行速度18ms,前輩的25ms。其實我感受我寫的沒有前輩的簡潔,但不知道爲何個人快一些。以後再仔細研究研究。
[function findMinIndex(arr,start){ var iMin=arr\[start\]; var iMinIndex=start; for(var i=start;i<arr.length;i++){ if(iMin>arr\[i\]){ iMin=arr\[i\]; iMinIndex=i; } } return iMinIndex; } for(var i=0;i<arr.length;i++){ var n=findMinIndex(arr,i); var tem; tem=arr\[n\]; arr\[n\]=arr\[i\]; arr\[i\]=tem; }][1]
其實,寫到這裏,應該結束了!可是我突然想起來,大學《數據結構》課上,我最喜歡的魏萊老師好像給咱們說過這個混合排序算法的。老師一步步引導咱們思考的場景還歷歷在目,我甚至均可以回想起老師說話時的語氣。但是,我卻還的差很少了,實在是可惡!!!