受大学室友的鼓动,我也打算利用公众平台来记录本身的前端知识积累,同时呢,本身总结的东西,总归会有局限性,但愿小伙伴能给我指点迷津。知识就是一张巨大的网,做为一名摸不清头绪的入学者,惟一能作的事情就是吐好每一根丝,丝拧成线,线再织成网。好啦,开机仪式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]
其实,写到这里,应该结束了!可是我突然想起来,大学《数据结构》课上,我最喜欢的魏莱老师好像给咱们说过这个混合排序算法的。老师一步步引导咱们思考的场景还历历在目,我甚至均可以回想起老师说话时的语气。但是,我却还的差很少了,实在是可恶!!!