js中的sort排序原理

一、问题的起因

偶然发现,在某些浏览器中显示的图表,日期排序混乱,如下图。

逐步排查原因:

1、接口返回的数据没有问题

2、大部分浏览器显示没有问题,只有Chrome浏览器有问题

3、新版本的Chrome浏览器没有问题,出现问题的浏览器版本在70以下

二、真相只有一个

      考虑到谷歌浏览器在70版本后,对sort方法进行了调整,遂定位到问题的原因为sort排序的问题。为了更直观的感受到不同版本浏览器中排序结果区别,在控制台中同时执行了以下排序操作。

var a = [10,5,40,25,1000,1]; 
a.sort(function(){
  return -1;
});

      根据sort方法的定义,以上代码是将a数组倒序显示。在72.0版本中,执行结果如下

      跟预期结果一致,没有问题。然而在69.0版本中结果却完全相反。

三、我的猜想

      看到这个结果,我想知道Chrome V8引擎,在进行排序算法时,究竟做了什么。

      使用Chrome版本 73.0.3683.86(正式版本)(64 位)来验证,首先在控制台中对一个数组进行升序排序。

var array = [4, 2, 5, 3, 1];
function compare(a, b) {
  console.log(a,b);
  return a - b;
}
array.sort(compare);

      输出结果

      第一行输出2 4,2-4<0,2移到4前面,数组为[2,4,5,3,1]

      第二行输出5 2,5-2>0,数组不变

      第三行输出5 4,5-4>0,数组不变

      根据前三行的输出规律,接下来输出依次应该是3 2,3 4,3 5,然而第四行却直接输出了3 4,这是因为算法使用了二分法,提高比较效率,3-4<0,3移到4前面,数组为[2,3,4,5,1]。

      由于3<4,所以第五行直接比较3 2,3-2>0,数组不变

      第六行,依旧按照二分法,从1 4,开始比较,1-4<0,1移到4前面,数组为[2,3,1,4,5]

      同理,第七行结果为[2,1,3,4,5],第八行结果为[1,2,3,4,5],排序完毕。

四、验证猜想

      为了验证上面推理的正确性,换一个数组验证一遍,结果如下

      第一行,5-10<0,5移到10前面,结果[5,10,40,25,1000,1]

      第二行,40-5>0,数组不变

      第三行,40-10>0,数组不变

      第四行,采用二分法,直接比较25 10,25-10>0,数组不变

      第五行,由于25大于10,所以比较25 40,25-40<0,25移到40前面,结果[5,10,25,40,1000,1]

      第六行,采用二分法,比较1000 25,1000-25>0,数组不变

      第七行,由于1000大于25,所以比较1000 40,1000-40>0,数组不变

      第八行,采用二分法,比较1 25,1-25<0,1移到25前面,结果[5,10,1,25,40,1000]

      第九行,由于1<25,所以比较1 10,1-10<0,1移到10前面,结果[5,1,10,25,40,1000]

      第十行,同理,结果为[1,5,10,25,40,1000],排序结束。与上述推理结果完全一致。

五、猜想的延伸

      当排序的数组很长的时候,每一次比较都会是一次二分,我后续使用长数组验证过了,由于数组太长,这里就不一行行来验证了。若有错误和其他更好的猜想,欢迎指正和提出。

  • 10
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值