当前位置: 首页 > news >正文

js排序篇----快速排序,选择排序,冒泡排序,希尔排序

为什么80%的码农都做不了架构师?>>>   hot3.png

能上代码的尽量不解释,用代码去反向理解文字这是我推崇的,所以请把重点放在代码理解上.

真实开发中 会直接用方法 sort 如下:

let arr = [2,34,242,12,3,2,23,3];

arr.sort((a,b) => a-b);//正序 等同于 arr.sort();
console.log(arr);// [2, 2, 3, 3, 12, 23, 34, 242]


arr.sort((a,b) => b-a);//倒序 等同于 arr.sort().reverse()
console.log(arr); //[242, 34, 23, 12, 3, 3, 2, 2]

但是对于数据量大的处理还是需要通过算法完成.

 

快速排序

"快速排序"的思想很简单,整个排序过程只需要三步

  1. 在数据集之中,选择一个元素作为"基准"(pivot)。
  2. 所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
  3. 对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。

举个例子:(红色为基准)
   数据值:{85, 24, 63, 45, 17, 31, 96, 50}

   第一步:{85, 24, 63, 45, 17, 31, 96, 50}  #45为基准

   第二步:{24,17,31} 45 {85,63,96,50}  #左边为小于45集合 右边为大于45集合

   第三步:17 {24,31} 45 {50} 63 {85,96} #左右集合继续重复一,二步骤

   第四步:17 24 {31} 45 50 63 85 {96} #同上

   第五步:17 24 31 45 50 63 85 96 #当左右集合只有一个元素即可返回

具体代码实现如下:

var quickSort = function(arr) {

  if (arr.length <= 1) { return arr; } //当子元素只有一个 返回

  var pivotIndex = Math.floor(arr.length / 2); //向下取整 算出基准索引

  var pivot = arr.splice(pivotIndex, 1)[0];//获取基准 这段话可以写成 var pivot = arr[pivotIndex];
  var left = [];//小于基准的左集合

  var right = [];//大于基准的右集合

  for (var i = 0; i < arr.length; i++){

    if (arr[i] < pivot) {

      left.push(arr[i]);

    } else {

      right.push(arr[i]);

    }

  }

  return quickSort(left).concat([pivot], quickSort(right)); //递归 左右集合继续对比 到返回后的数组合并

};

console.log(quickSort([85, 24, 63, 45, 17, 31, 96, 50]));
//(8) [17, 24, 31, 45, 50, 63, 85, 96]

 

选择排序

算法步骤:

  1. 在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
  2. 从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
  3. 重复第二步,直到所有元素均排序完毕。

举个例子:(红色为最小值)
   数据值:{85, 24, 63, 45, 17, 31, 96, 50}

   第一步: 遍历索引 从0开始 (下面为索引为0的小步骤)

  1. {85, 24, 63, 45, 17, 31, 96, 50}  //默认为85 依次从左往右对比
  2. {85, 24, 63, 45, 17, 31, 96, 50}  //24小于85 变为最小值
  3. {85, 24, 63, 45, 17, 31, 96, 50}  //63大于24 最小值没变
  4. {85, 24, 63, 45, 17, 31, 96, 50}  //45大于24 最小值没变
  5. {85, 24, 63, 45, 17, 31, 96, 50}  //17小于24 变为最小值
  6. {85, 24, 63, 45, 17, 31, 96, 50}  //31大于17 最小值没变
  7. 以此类推 所有元素均排序完毕 , 选择出最小值为17与索引为0的85互换位置 ,数组处理后为:{17, 24, 63, 45, 85, 31, 96, 50}

   第二步:遍历索引从1开始(重复第一步骤)

   .........

  第N步后:直到所有元素均排序完毕

 具体代码实现如下:

 var selectionSort = function(arr) {

        var len = arr.length,minIndex, temp;
        for (var i = 0; i < len - 1; i++) {
            minIndex = i;
            for (var j = i + 1; j < len; j++) {
                if (arr[j] < arr[minIndex]) {     // 寻找最小的数
                    minIndex = j;                 // 将最小数的索引保存
                }
            }
            temp = arr[i];
            arr[i] = arr[minIndex];
            arr[minIndex] = temp;
        }
        return arr;
    };

    console.log(selectionSort([85, 24, 63, 45, 17, 31, 96, 50]));
    //[17, 24, 31, 45, 50, 63, 85, 96]

 

冒泡排序     

算法步骤: 

  1. 依次比较相邻的两个数,如果不符合排序规则,则调换两个数的位置。这样一遍比较下来,能够保证最大(或最小)的数排在最后一位
  2. 再对最后一位以外的数组,重复前面的过程,直至全部排序完成。

继续举例: (红色为最大值)   

 数据值:{85, 24, 63, 45, 17, 31, 96, 50}

   第一步: 遍历索引 从0开始 (下面为索引为0的小步骤)

  1. {85, 24, 63, 45, 17, 31, 96, 50}  //默认为85 依次从左往右对比
  2. {24, 85, 63, 45, 17, 31, 96, 50}  //24小于85 互换位置
  3. {24, 63, 85, 45, 17, 31, 96, 50}  //63小于85 互换位置
  4. {24, 63, 45, 85, 17, 31, 96, 50}  //45小于85 互换位置
  5. {24, 63, 45,  17,85, 31, 96, 50}  //17小于85 互换位置
  6. {24, 63, 45,  17,31,85, 96, 50}   //96大于85 不换位置 
  7. {24, 63, 45,  17,31,85, 50, 96}   //96大于50 互换位置 第一次遍历结束

   第二步:遍历索引 从0开始(重复第一步骤) 遍历次数<最大索引-1

   .........

  第N步后:遍历索引 从0开始  最大索引-n === 0 为止

 具体代码实现如下:

 var bubbleSort = function(arr) {
        var len = arr.length,i,j;
        for (i = 0; i < len - 1; i++){
            for (j = 0, j < len - 1 - i; j++){ //i位以外的数组,重复循环
                if (arr[j] > arr[j + 1]){
                    var temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
        return arr;
    };
    console.log(bubbleSort([85, 24, 63, 45, 17, 31, 96, 50]));

 

希尔排序

算法步骤:

  1. 按照实际需要设定一个步长(我们这里设定 fraction = arr.length / 2,即步长为 5)。这样就可以将数列分组,并对每个分组执行插入排序。所有分组都执行完插入排序,视为第一轮排序完成
  2. 待整个序列中的记录基本有序时,再对全体记录进行依次直接插入排序

数据值:{85, 24, 63, 45, 17, 31, 96, 50}

   第一步: 计算步长= 8/2 = 4;即分割为4组
      {85, 24, 63, 45, 17, 31, 96, 50}
      85 ************17***********
      ****24************31********

      ********63***********96*****
     *************45***********50

     排序:   

     17************85*************
     ****24************31*********

      *******63************96*****
     ***********45*************50

    排序后:

    {17, 24, 63, 45, 85, 31, 96, 50}

   第二步:计算步长= 上次步长/2 = 5/2 = 2 ;即分割为2组
  {17, 24, 63, 45, 85, 31, 96, 50}
  17******63****85****96*****

  ****24*****45*****31*****50

  排序后:{17,24,63,31,85,45,96,50}

  第三步:计算步长= 上次步长/2 = 2/2 = 1 ;即分割为1组
  排序后:{17, 24, 31, 45, 50, 63, 85, 96}//结束

 具体代码实现如下:

var shellSort = function(list) {
        var gap = Math.floor( list.length / 2 );//第一次计算步长

        while( gap > 0 ) {//步长为0 不再执行

            for( i = gap; i < list.length; i++ ) {

                var temp = list[i];

                for( j = i; j >= gap && list[j - gap] > temp; j -= gap ) {

                    list[j] = list[j - gap];
                }

                list[j] = temp;

            }

            gap = Math.floor( gap / 2 );//向下取整 重新计算步长
        }


        return list;
    }

 

转载于:https://my.oschina.net/oslph/blog/3013686

相关文章:

  • Service Worker
  • 《文献管理与信息分析》第五章 学习笔记
  • 一些集群操作以及问题查询
  • GraphQL学习过程应该是这样的
  • Spark -- WordCount程序
  • Java SE 12扩展Switch语句/表达式完整指南
  • java中具有继承关系的类及其对象初始化顺序
  • 和平之翼代码生成器SMEU版 4.0.0 Beta5 宝船公布
  • 去哪里学习行业知识?
  • java概述
  • Kubeadm证书过期问题修复方法之一:通过修改kubeadm源码
  • 区块链分支循环
  • java中【派生类、基类、父类、子类】
  • FydeOS VM for VMWare v6.0 Preview1 发布
  • 浏览器缓存机制
  • 30秒的PHP代码片段(1)数组 - Array
  • 4个实用的微服务测试策略
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • Java 最常见的 200+ 面试题:面试必备
  • JavaScript 一些 DOM 的知识点
  • Java方法详解
  • js继承的实现方法
  • Linux各目录及每个目录的详细介绍
  • windows下mongoDB的环境配置
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 回顾 Swift 多平台移植进度 #2
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 每天10道Java面试题,跟我走,offer有!
  • 如何学习JavaEE,项目又该如何做?
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 我看到的前端
  • ​二进制运算符:(与运算)、|(或运算)、~(取反运算)、^(异或运算)、位移运算符​
  • ###项目技术发展史
  • #每天一道面试题# 什么是MySQL的回表查询
  • (1)Nginx简介和安装教程
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (七)Knockout 创建自定义绑定
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (转载)从 Java 代码到 Java 堆
  • *p++,*(p++),*++p,(*p)++区别?
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .NET 8.0 发布到 IIS
  • .NET HttpWebRequest、WebClient、HttpClient
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .NET/C# 阻止屏幕关闭,阻止系统进入睡眠状态
  • .net6Api后台+uniapp导出Excel
  • .NetCore实践篇:分布式监控Zipkin持久化之殇
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • .Net下C#针对Excel开发控件汇总(ClosedXML,EPPlus,NPOI)
  • /usr/bin/python: can't decompress data; zlib not available 的异常处理
  • [].slice.call()将类数组转化为真正的数组
  • [Android Studio] 开发Java 程序
  • [CareerCup] 13.1 Print Last K Lines 打印最后K行
  • [codeforces]Levko and Permutation