受大学室友的鼓动,我也打算利用公众平台来记录自己的前端知识积累,同时呢,自己总结的东西,总归会有局限性,希望小伙伴能给我指点迷津。知识就是一张巨大的网,作为一名摸不清头绪的入学者,唯一能做的事情就是吐好每一根丝,丝拧成线,线再织成网。好啦,开机仪式over,废话不多说了啦...


关于Sort()这个函数,决定研究它是因为在看阮老师的箭头函数时,最后有一个小练习:
请使用箭头函数简化排序时传入的函数:

var arr = [10, 20, 1, 2];
arr.sort((x, y) => {
???
});
console.log(arr); // [1, 2, 10, 20]

因为之前js基础也不扎实,没有get到这个题的核心,想了想写了写,最后放弃了,看了评论里的答案。我的天,就一句——return x - y;,当时我就觉得这个函数太神奇了,这么简单的解决了数组排序。(上大学那会,懒惰致死的我所有排序算法原理都明明白白,但是从来没有写过,于是就...后悔莫及阿)

sort()函数定义

了解原理先从函数定义入手,于是乎...从W3C上搬了一段解释:

定义和用法: sort() 方法用于对数组的元素进行排序。

语法: arrayObject.sort(sortby)

返回值: 对数组的引用。请注意,数组在原数组上进行排序,不生成副本。

说明:

  1. 如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。
  2. 如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:
    若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
    若 a 等于 b,则返回 0。
    若 a 大于 b,则返回一个大于 0 的值。

sort排序的过程中发生了什么呢

此处参考了前辈的文章链接描述,我就特别傻,断点打到sort()函数这一行,然后step-into执行,不断在console里打印arr。。。傻的一p
怎么查看sort()方法是如果实现排序的呢?我们可以在比较函数里把a,b及数组输出一下,看看是否能够看出使用的排序算法。

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,不需要调整位置。   

  第二次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, 还仅仅是覆盖,继续往下!
  第七、八、九次,-1依次和5,3,1做了比较,并且5,3,1都移动了一次位置。

  我们得出了结论:sort()方法是使用的冒泡和插入两种方式结合进行排序的。

回顾冒泡和插入排序

这里我用自己的话总结一下:
冒泡排序:

  1. 第一轮:从第一个元素开始,相邻元素比较,前者比后者大,互换位置,下标加一;再继续相邻元素比较,大的元素移到后面,下标加一再比较...这样一轮比较下来,最后一个元素一定是数组里最大的元素
  2. 第二轮及之后:好啦,现在最后一个元素(即最大的元素)确定了,将其排除在外,我们再来从头对比除它之外的元素,将倒数第二大的元素移到倒数第二个位置。以此类推,每一轮确定一个元素的位置,就像小鱼吐泡泡一样,大的泡泡一点一点往上移
function bubbel(arr) {
var len=arr.length;
for(var i=0; i&lt;len; i++) {
for(var j=0; j&lt;len; j++) {
if(arr[j] &gt; 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 &lt; len; i++){
tmp = result[i];
j = i - 1;
while(j&gt;=0 &amp;&amp; tmp &lt; result[j]){
result[j+1] = result[j];
j--;
}
result[j+1] = tmp;
}
return result;
}

sort()的正面目来啦

前面铺垫了这么多,终于到了今天的重点——冒泡排序和插入排序是如何混合使用的?即sort()实现的原理。先上我的代码!! 时隔多年,我终于不再懒惰,勇敢写出我的代码。希望努力不要太晚~

var arr = [1, 8, 3, 5, -1];
var len = arr.length;
function compareSet(temp, compare_i){
for(var i = compare_i; i &gt; 0; i--){
if(temp &gt; arr[i-1]){
arr[i] = temp;
break;
}
else{
arr[i] = arr[i-1];
arr[i-1] = temp;
}
}
}
for(var i = 0; i &lt; len; i++){
if(arr[i] &gt; 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&lt;arr.length;i++){
if(iMin&gt;arr\[i\]){
iMin=arr\[i\];
iMinIndex=i;
}
}
return iMinIndex;
}
for(var i=0;i&lt;arr.length;i++){
var n=findMinIndex(arr,i);
var tem;
tem=arr\[n\];
arr\[n\]=arr\[i\];
arr\[i\]=tem;
}][1]

其实,写到这里,应该结束了!但是我忽然想起来,大学《数据结构》课上,我最喜欢的魏莱老师好像给我们说过这个混合排序算法的。老师一步步引导我们思考的场景还历历在目,我甚至都可以回想起老师说话时的语气。可是,我却还的差不多了,实在是可恶!!!

原文地址:https://segmentfault.com/a/1190000017026510

小试牛刀之sort()排序的实现的更多相关文章

  1. 2.sort 排序命令讲解

    sort命令  sort:文本排序,仅仅是对显示文件的排序,而不影响源文件的顺序,是根据ASSII码     的字符升序来排列的.        -n:安装数值大小从小到大排列 ,默认是升序.     ...

  2. 反向输出及sort排序

    建立条件:#include "algorithm"引用这个头文件 1.reverse 的用法,反向排序,由自己输入5个数: 1 2 3 4 5 for (int i = 0; i ...

  3. JAVA Collections工具类sort()排序方法

    主要分析内容: 一.Collections工具类两种sort()方法 二.示例 一.Collections工具类两种sort()方法 格式一: public static <T extends ...

  4. javascript:算法之数组sort排序

    数组sort排序 sort比较次数,sort用法,sort常用 描述 方法sort()将在原数组上对数组元素进行排序,即排序时不创建新的数组副本.如果调用方法sort()时没有使用参数,将按字母顺序( ...

  5. sort排序

    /*问题 L: 使用sort排序题目描述标准库的sort函数给我们提供了一个很方便的排序的方法,光听别人说方便不顶事,得自己亲自实践一下才能体会到它的方便之处. 输入每组包含多组数据,每组数据第一行包 ...

  6. [转] C++的STL库,vector sort排序时间复杂度 及常见容器比较

    http://www.169it.com/article/3215620760.html http://www.cnblogs.com/sharpfeng/archive/2012/09/18/269 ...

  7. List<T>.Sort() 排序的用法

    List<T> 可以通过 .Sort()进行排序,但是当 T 对象为自定义类型时(比如自定义模型),就需要 IComparable接口重写其中的方法来实现,实现代码如下: class Pr ...

  8. sort排序中的坑

    问题的产生原因: 在一篇阿里面试题的跟帖中,很多人应用sort()方法对数组进行排序.看似合情合理的代码,运行结果却频频出错.为什么呢?因为很多人都忽略掉了一点,那就是sort()排序默认情况下是按A ...

  9. STL vector+sort排序和multiset/multimap排序比较

    由 www.169it.com 搜集整理 在C++的STL库中,要实现排序可以通过将所有元素保存到vector中,然后通过sort算法来排序,也可以通过multimap实现在插入元素的时候进行排序.在 ...

随机推荐

  1. 训练1-H

    小明今年3岁了, 现在他已经能够认识100以内的非负整数, 并且能够进行100以内的非负整数的加法计算. 对于大于等于100的整数, 小明仅保留该数的最后两位进行计算, 如果计算结果大于等于100, ...

  2. LVM实践

    [root@ftp:/root] > fdisk -l Disk /dev/sda: 53.7 GB, 53687091200 bytes, 104857600 sectors Units = ...

  3. 【hihocoder 1303】模线性方程组

    [题目链接]:http://hihocoder.com/problemset/problem/1303 [题意] [题解] /* x % m[1] = r[1] x % m[2] = r[2] x = ...

  4. 0111mysql如何选择Join的顺序

    本文通过一个案例来看看MySQL优化器如何选择索引和JOIN顺序.表结构和数据准备参考本文最后部分"测试环境".这里主要介绍MySQL优化器的主要执行流程,而不是介绍一个优化器的各 ...

  5. 《编程导论(Java)&#183;7.4.4 String对象问题》

    String是Java API中使用频率第一的类,曾经在CSDN论坛上.至少每一个月都有相关的贴子,讨论==和equals(). 本节介绍这一部分的内容,也有一个重要更正. String文字在程序中被 ...

  6. hdoj 5092 Seam Carving 【树塔DP变形 + 路径输出】 【简单题】

    Seam Carving Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tot ...

  7. Hit 2255 Not Fibonacci

    今天下午刚起来眼睛就比較涨,,并且还有点恶心,唉.结果一直不在状态.并且这个题太坑了.. .. 点击此处即可传送 Hit 2255 Maybe ACMers of HIT are always fon ...

  8. 一起talk C栗子吧(第一百一十九回:C语言实例--线程死锁三)

    各位看官们.大家好,上一回中咱们说的是线程死锁的样例,这一回咱们继续说该样例.闲话休提,言归正转.让我们一起talk C栗子吧! 看官们,由于篇幅的原因我们在上一回仅仅介绍了死锁发生的第一种原因,今天 ...

  9. Qt 图像处理之 灰度变换

    对图像的亮度.对照度进行变换是非经常常使用的一种图像处理操作,可是Qt 本身却没有提供对应的功能代码.因此我写了个简单的类来实现这些操作.我把这个类称为 BrightnessMapper. 代码例如以 ...

  10. 一个Python项目的创建架构

    要进行Python项目的编写,很多人刚开始一筹莫展,不知道该如何去构建一个项目,现在粗略的描述一下一个项目的创建过程,供大家参考了解一下: 大家可以先忽略其中创建的函数 ,每个包的含义都有定义,大家可 ...