基于js 各种排序方法和sort方法的区别(详解)


Posted in Javascript onJanuary 03, 2018

今天突发奇想,想明白sort方法是否比各种排序都有优势,所以就参考别人的代码,做了一个测试,结果令人惊讶啊,上代码。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
  <title>图片列表生成交互组件</title>
  <style>
    * {
      margin: 0;
      border: 0;
    }
    html, body {
      height: 100%;
    }
    #div {
      height: 100%;
      width: 100%;
    }
  </style>
</head>
<body>
<div id="div"></div>
<script src="myNeedExtend.js"></script>
<script>
  // ---------- 一些排序算法
  Sort = {
    // 利用sort进行排序
    systemSort:function(array){
      return array.sort(function(a, b){
        return a - b;
      });
    },
    // 冒泡排序
    bubbleSort:function(array){
      var i = 0, len = array.length,
        j, d;
      for(; i<len; i++){
        for(j=0; j<len; j++){
          if(array[i] < array[j]){
            d = array[j];
            array[j] = array[i];
            array[i] = d;
          }
        }
      }
      return array;
    },
    // 快速排序
    quickSort:function(array){
      //var array = [8,4,6,2,7,9,3,5,74,5];
      //var array =[0,1,2,44,4,324,5,65,6,6,34,4,5,6,2,43,5,6,62,43,5,1,4,51,56,76,7,7,2,1,45,4,6,7];
      var i = 0;
      var j = array.length - 1;
      var Sort = function(i, j){
        // 结束条件
        if(i == j ){ return };
        var key = array[i];
        var tempi = i; // 记录开始位置
        var tempj = j; // 记录结束位置
        while(j > i){
          // j <<-------------- 向前查找
          if(array[j] >= key){
            j--;
          }else{
            array[i] = array[j]
            //i++ ------------>>向后查找
            while(j > ++i){
              if(array[i] > key){
                array[j] = array[i];
                break;
              }
            }
          }
        }
        // 如果第一个取出的 key 是最小的数
        if(tempi == i){
          Sort(++i, tempj);
          return ;
        }
        // 最后一个空位留给 key
        array[i] = key;
        // 递归
        Sort(tempi, i);
        Sort(j, tempj);
      }
      Sort(i, j);
      return array;
    },
    // 插入排序
    insertSort:function(array){
      // http://baike.baidu.com/image/d57e99942da24e5dd21b7080
      // http://baike.baidu.com/view/396887.htm
      // var array = [0,1,2,44,4,324,5,65,6,6,34,4,5,6,2,43,5,6,62,43,5,1,4,51,56,76,7,7,2,1,45,4,6,7];
      var i = 1, j, temp, key, len = array.length;
      for(; i < len; i++){
        temp = j = i;
        key = array[j];
        while(--j > -1){
          if(array[j] > key){
            array[j+1] = array[j];
          }else{
            break;
          }
        }
        array[j+1] = key;
      }
      return array;
    },
    // 希尔排序
    shellSort:function(array){
      // http://zh.wikipedia.org/zh/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F
      // var array = [13,14,94,33,82,25,59,94,65,23,45,27,73,25,39,10];
      // var tempArr = [1750, 701, 301, 132, 57, 23, 10, 4, 1];
      // reverse() 在维基上看到这个最优的步长 较小数组
      var tempArr = [1031612713, 217378076, 45806244, 9651787, 2034035, 428481, 90358, 19001, 4025, 836, 182, 34, 9, 1];
      //针对大数组的步长选择
      var i = 0;
      var tempArrLength = tempArr.length;
      var len = array.length;
      var len2 = parseInt(len/2);
      for(;i < tempArrLength; i++){
        if(tempArr[i] > len2){
          continue;
        }
        tempSort(tempArr[i]);
      }
      // 排序一个步长
      function tempSort(temp){
        //console.log(temp) 使用的步长统计
        var i = 0, j = 0, f, tem, key;
        var tempLen = len%temp > 0 ? parseInt(len/temp) + 1 : len/temp;
        for(;i < temp; i++){// 依次循环列
          for(j=1;/*j < tempLen && */temp * j + i < len; j++){
            //依次循环每列的每行
            tem = f = temp * j + i;
            key = array[f];
            while((tem-=temp) >= 0){
              // 依次向上查找
              if(array[tem] > key){
                array[tem+temp] = array[tem];
              }else{
                break;
              }
            }
            array[tem + temp ] = key;
          }
        }
      }
      return array;
    }
  };
  testArrs = [];
  for (var i = 10000000; i > 0; i--) {
    testArrs.push(i);
  }
  function test(fun,arr) {
    console.log(arr);
    var oldTime = +new Date();
    var new_arr = Sort[fun](arr);
    var newTime = +new Date();
    console.log(new_arr);
    console.log(newTime-oldTime);
  }
  /*
  * sort排序 systemSort
  * 冒泡排序 bubbleSort
  * 快速排序 quickSort
  * 插入排序 insertSort
  * 希尔排序 shellSort
  *
  * */
  test("systemSort",testArrs);
</script>
</body>
</html>

上面的方法通过测试时间,然后分析哪个排序方法省时,时间就是生命,用对正确的方法,就能省下好多时间,尤其是大数据运行的时候。

首先看运行处理10000个长度数组时的所用的时间:

* sort排序 systemSort 11
* 冒泡排序 bubbleSort 169
* 快速排序 quickSort 144
* 插入排序 insertSort 139
* 希尔排序 shellSort 3

测试十万长的数组数据:

* sort排序 systemSort 63
* 冒泡排序 bubbleSort 16268
* 快速排序 quickSort 直接报错
* 插入排序 insertSort 13026
* 希尔排序 shellSort 8

测试一百万的长度的数组:

* sort排序 systemSort 575
* 冒泡排序 bubbleSort 时间未知
* 快速排序 quickSort 直接报错
* 插入排序 insertSort 直接崩溃
* 希尔排序 shellSort 93

测试一千万长的数组:

* sort排序 systemSort 7039
* 冒泡排序 bubbleSort 没测
* 快速排序 quickSort 没测
* 插入排序 insertSort 没测
* 希尔排序 shellSort 1225

测试一亿长的数组:

* sort排序 systemSort 直接崩溃
* 冒泡排序 bubbleSort 没测
* 快速排序 quickSort 没测
* 插入排序 insertSort 没测
* 希尔排序 shellSort 19864

最后通过测试,在最坏的情况下,发现希尔排序还是最好,竟然比系统的sort排序都快,确实令人惊讶,大家这样就能看出来在什么情况需要使用什么方法进行排序了吧

然后我们进行随机情况进行测试:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
  <title>图片列表生成交互组件</title>
  <style>
    * {
      margin: 0;
      border: 0;
    }
    html, body {
      height: 100%;
    }
    #div {
      height: 100%;
      width: 100%;
    }
  </style>
</head>
<body>
<div id="div"></div>
<script src="myNeedExtend.js"></script>
<script>
  // ---------- 一些排序算法
  Sort = {
    // 利用sort进行排序
    systemSort:function(array){
      return array.sort(function(a, b){
        return a - b;
      });
    },
    // 冒泡排序
    bubbleSort:function(array){
      var i = 0, len = array.length,
        j, d;
      for(; i<len; i++){
        for(j=0; j<len; j++){
          if(array[i] < array[j]){
            d = array[j];
            array[j] = array[i];
            array[i] = d;
          }
        }
      }
      return array;
    },
    // 快速排序
    quickSort:function(array){
      //var array = [8,4,6,2,7,9,3,5,74,5];
      //var array =[0,1,2,44,4,324,5,65,6,6,34,4,5,6,2,43,5,6,62,43,5,1,4,51,56,76,7,7,2,1,45,4,6,7];
      var i = 0;
      var j = array.length - 1;
      var Sort = function(i, j){
        // 结束条件
        if(i == j ){ return };
        var key = array[i];
        var tempi = i; // 记录开始位置
        var tempj = j; // 记录结束位置
        while(j > i){
          // j <<-------------- 向前查找
          if(array[j] >= key){
            j--;
          }else{
            array[i] = array[j]
            //i++ ------------>>向后查找
            while(j > ++i){
              if(array[i] > key){
                array[j] = array[i];
                break;
              }
            }
          }
        }
        // 如果第一个取出的 key 是最小的数
        if(tempi == i){
          Sort(++i, tempj);
          return ;
        }
        // 最后一个空位留给 key
        array[i] = key;
        // 递归
        Sort(tempi, i);
        Sort(j, tempj);
      }
      Sort(i, j);
      return array;
    },
    // 插入排序
    insertSort:function(array){
      // http://baike.baidu.com/image/d57e99942da24e5dd21b7080
      // http://baike.baidu.com/view/396887.htm
      // var array = [0,1,2,44,4,324,5,65,6,6,34,4,5,6,2,43,5,6,62,43,5,1,4,51,56,76,7,7,2,1,45,4,6,7];
      var i = 1, j, temp, key, len = array.length;
      for(; i < len; i++){
        temp = j = i;
        key = array[j];
        while(--j > -1){
          if(array[j] > key){
            array[j+1] = array[j];
          }else{
            break;
          }
        }
        array[j+1] = key;
      }
      return array;
    },
    // 希尔排序
    shellSort:function(array){
      // http://zh.wikipedia.org/zh/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F
      // var array = [13,14,94,33,82,25,59,94,65,23,45,27,73,25,39,10];
      // var tempArr = [1750, 701, 301, 132, 57, 23, 10, 4, 1];
      // reverse() 在维基上看到这个最优的步长 较小数组
      var tempArr = [1031612713, 217378076, 45806244, 9651787, 2034035, 428481, 90358, 19001, 4025, 836, 182, 34, 9, 1];
      //针对大数组的步长选择
      var i = 0;
      var tempArrLength = tempArr.length;
      var len = array.length;
      var len2 = parseInt(len/2);
      for(;i < tempArrLength; i++){
        if(tempArr[i] > len2){
          continue;
        }
        tempSort(tempArr[i]);
      }
      // 排序一个步长
      function tempSort(temp){
        //console.log(temp) 使用的步长统计
        var i = 0, j = 0, f, tem, key;
        var tempLen = len%temp > 0 ? parseInt(len/temp) + 1 : len/temp;
        for(;i < temp; i++){// 依次循环列
          for(j=1;/*j < tempLen && */temp * j + i < len; j++){
            //依次循环每列的每行
            tem = f = temp * j + i;
            key = array[f];
            while((tem-=temp) >= 0){
              // 依次向上查找
              if(array[tem] > key){
                array[tem+temp] = array[tem];
              }else{
                break;
              }
            }
            array[tem + temp ] = key;
          }
        }
      }
      return array;
    }
  };
  testArrs = [];
  for (var i = 0; i < 10000000; i++) {
    testArrs.push(Math.random());
  }
  function test(fun,arr) {
    var oldTime = +new Date();
    var new_arr = Sort[fun](arr);
    var newTime = +new Date();
    console.log(fun);
    console.log(newTime-oldTime);
  }
  /*
  * sort排序 systemSort
  * 冒泡排序 bubbleSort
  * 快速排序 quickSort
  * 插入排序 insertSort
  * 希尔排序 shellSort
  *
  * */
  test("systemSort",testArrs);
  //test("bubbleSort",testArrs);
  //test("quickSort",testArrs);
  test("insertSort",testArrs);
  test("shellSort",testArrs);
</script>
</body>
</html>

测试一千万长的数组:

* sort排序 systemSort 8842
* 冒泡排序 bubbleSort 没测
* 快速排序 quickSort 没测
* 插入排序 insertSort 45
* 希尔排序 shellSort 1133

在未知的情况和比较好的情况下,插入排序的效率最高

以上这篇基于js 各种排序方法和sort方法的区别(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
枚举JavaScript对象的函数
Dec 22 Javascript
JQuery的ajax基础上的超强GridView展示
Sep 18 Javascript
Javascript中获取出错代码所在文件及行数的代码
Sep 23 Javascript
Jquery Autocomplete 结合asp.net使用要点
Oct 29 Javascript
js实时监听文本框状态的方法
Apr 26 Javascript
使用jQuery和PHP实现类似360功能开关效果
Feb 12 Javascript
使用javascript做的一个随机点名程序
Feb 13 Javascript
jQuery子属性过滤选择器用法分析
Feb 10 Javascript
jQuery实现美观的多级动画效果菜单代码
Sep 06 Javascript
JavaScript表单焦点自动切换代码
Jul 24 Javascript
AngularJS 与Bootstrap实现表格分页实例代码
Oct 14 Javascript
html5以及jQuery实现本地图片上传前的预览代码实例讲解
Mar 01 jQuery
vue项目中用cdn优化的方法
Jan 03 #Javascript
不到200行 JavaScript 代码实现富文本编辑器的方法
Jan 03 #Javascript
利用原生js实现html5小游戏之打砖块(附源码)
Jan 03 #Javascript
js判断文件类型大小并给出提示的实现方法
Jan 03 #Javascript
js登录滑动验证的实现(不滑动无法登陆)
Jan 03 #Javascript
Angular实现下拉框模糊查询功能示例
Jan 03 #Javascript
Node使用Sequlize连接Mysql报错:Access denied for user ‘xxx’@‘localhost’
Jan 03 #Javascript
You might like
PHP中OpenSSL加密问题整理
2017/12/14 PHP
PHP实现普通hash分布式算法简单示例
2018/08/06 PHP
PHP单例模式数据库连接类与页面静态化实现方法
2019/03/20 PHP
Javascript笔记一 js以及json基础使用说明
2010/05/22 Javascript
修改jquery里的dialog对话框插件为框架页(iframe) 的方法
2010/09/14 Javascript
jQuery中wrapAll()方法用法实例
2015/01/16 Javascript
JS面向对象编程详解
2016/03/06 Javascript
js不间断滚动的简单实现
2016/06/03 Javascript
AngularJS基础 ng-non-bindable 指令详细介绍
2016/08/02 Javascript
AngularJS select加载数据选中默认值的方法
2018/02/28 Javascript
vue页面加载闪烁问题的解决方法
2018/03/28 Javascript
Angular4.x通过路由守卫进行路由重定向实现根据条件跳转到相应的页面(推荐)
2018/05/10 Javascript
vue实现点击追加选中样式效果
2019/11/01 Javascript
微信小程序实现页面浮动导航
2020/01/08 Javascript
[01:01]2020完美高校联赛(秋)西安落幕
2021/03/11 DOTA
python抓取网页图片示例(python爬虫)
2014/04/27 Python
Django中URLconf和include()的协同工作方法
2015/07/20 Python
深入解析Python编程中super关键字的用法
2016/06/24 Python
Python操作json的方法实例分析
2018/12/06 Python
Anaconda使用IDLE的实现示例
2020/09/23 Python
浅谈关于html5中图片抛物线运动的一些心得
2018/01/09 HTML / CSS
英国高档时尚男装购物网站:MR PORTER
2016/08/09 全球购物
美国浴缸、水槽和水龙头购物网站:Vintage Tub & Bath
2019/11/05 全球购物
N:Philanthropy官网:美国洛杉矶基础款服装
2020/06/09 全球购物
大专毕业生自我评价分享
2013/11/10 职场文书
船舶专业个人求职信范文
2014/01/02 职场文书
开学典礼感言
2014/02/16 职场文书
美国留学经济担保书
2014/05/20 职场文书
2014年化工厂工作总结
2014/11/25 职场文书
公务员个人年终总结
2015/02/12 职场文书
教师节随笔
2015/08/15 职场文书
pytorch中的numel函数用法说明
2021/05/13 Python
nginx配置文件使用环境变量的操作方法
2021/06/02 Servers
在Python中如何使用yield
2021/06/07 Python
详解Python函数print用法
2021/06/18 Python
MySQL一劳永逸永久支持输入中文的方法实例
2022/08/05 MySQL