文章出自个人博客 https://knightyun.github.io/2019/05/01/js-sort,转载请申明。


冒泡排序

冒泡排序即数组从头到尾,依次比较相邻两数的大小,不符合顺序则交换位置,一直循环直到排序完成。如果是升序排序,那么每一轮的一系列比较和交换之后,最大那个数一定会被排到最后(不信可以动手验证一下),可以理解为冒泡到最后,这样每一轮的最大那个数都冒到最后,所以每一轮需要比较的总数都在减少,直到剩一个数为止,序列就有序了,降序也是同样的道理;

// 输入值 _arr 为需要排序的数组,返回一个有序新数组
function bubbleSort(_arr) {var arr = _arr.concat();var len = arr.length;for (var i = len - 1; i > 0; i--) {for (var j = 0; j < i; j++) {if (arr[j] > arr[j + 1]) {let tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}return arr;
}

选择排序

选择排序即从数组第一个数到倒数第二个数,分别与后面的数中的选出的最值(升序就是最小值)进行比较,满足条件(升序就是大于最小值)就交换位置,然后完成排序。这里可以理解为先选择出最小值,然后与前面的数进行比较和交换,就不用像冒泡那样挨个比较和交换了;另外,这里为了交换方便,记录的最值其实是该值在数组中的索引,而不是实际值;

function selectSort(_arr) {var arr = _arr.concat();var len = arr.length;for (var i = 0; i < len - 1; i++) {var minIdx = i;for (var j = i + 1; j < len; j++) {if (arr[j] < arr[minIdx]) minIdx = j;}// 如果当前值已经是最小值,就可以不用交换,// 避免浪费时间if (minIdx !== i) {var tmp = arr[i];arr[i] = arr[minIdx];arr[minIdx] = tmp;}}return arr;
}

插入排序

插入排序即从第二个到最后一个数,分别与排在前面的有序序列(第一轮该序列只有一个数,肯定是有序的,之后每一轮结束这个有序序列都会增加)中的每个数进行比较,然后插入合适的位置使其有序,直到最后一个数插入时完成排序;

function insertSort(_arr) {var arr = _arr.concat();var len = arr.length;for (let i = 1; i < len; i++) {// 先将插入值(当前值)备份,方便后续插入操作let tmp = arr[i];// 插入值在有序序列中从右向左比较for (let j = i; j > 0; j--) {// 下面就是“插入”操作的实现:// 如果插入值小于比较值(j-1),则将前面的数向后挪一位,// 这样就可以把被插入的空间留出来了,并且在不断向前移动if (tmp < arr[j - 1]) {arr[j] = arr[j - 1];// 如果插入值大于或等于比较值,则把插入值放到这个比较值的后面// 也就是之前留出来的插入空间} else {arr[j] = tmp;break;}}}return arr;
}

快速排序

快速排序在数组中任选一个数(下面选第一个数)作中间值,然后将余下的数分别与其比较,比中间值小则放到左边,否则放右边,然后再进行递归,将放在左边和右边的数组分别作为新数组进行同样的排序操作,直到数组不能再分,最后将所有排序结果合并;这里快速可以理解为整个操作过程相比于其他方法简单快捷,找好任一个中间值后便将剩下的数挨个放入其左或右,而不用管左右数组是否有序,直到递归完成就整体有序了,至于排序是否快速就要看情况了;

// 方法一:
function quickSort(arr) {let len = arr.length;if (len < 2) {return arr;} else {let mid = arr[0], // 基准(中间值)left = [], // 放到基准左边的数right = []; // 放到基准右边的数for (let i = 1; i < len; i++) {if (arr[i] < mid) {left.push(arr[i]);} else {right.push(arr[i]);}}// 递归分割下去,不能分割时合并左中右数组返回return quickSort(left).concat(mid).concat(quickSort(right));}
}// 方法二:
function quickSort(arr) {let len = arr.length;if (len < 2) {return arr;} else {let midIdx = 0; // 基准值的索引// 这里执行的就是把值放入基准左边还是右边的操作for (let i = 1; i < len; i++) {// 由于基准是第一个数,并且是从左向右遍历,// 所以后面的遍历值如果小于基准就先删除再 unshift 到最前面,// 这样就实现了“放到左边”,// 如果大于或等于基准就不用管,也就“放到右边”了;if (arr[i] < arr[midIdx]) {arr.unshift(arr.splice(i, 1)[0]);midIdx++;}}return quickSort(arr.slice(0, midIdx)).concat(arr[midIdx]).concat(quickSort(arr.slice(midIdx + 1)));}
}// 经测试方法一比方法二快一些,数组越大相差倍数数量级也越大。
// 显而易见方法一在空间上消耗不少,所以在时间上占优势;

归并排序

归并排序递归地将数组分割为两个部分(左数组与右数组),直到不能再分,然后再定义一个合并函数,负责递归地将两部分合并为一个有序数组作为返回值;合并函数其实会是合并两个有序的数组,合并方法便是分别将两数组第一个数取出(删除)放入返回数组中,至于两个数先放哪一个,可以通过比较大小来确定;所以这里的归并可以理解为递地合为一个有序序列;

function mergeSort(arr) {if (arr.length < 2) {// 不能再分时返回数组,执行之后的合并操作return arr;} else {// 将数组分割成两部分let mid = Math.ceil(arr.length / 2);let left = arr.slice(0, mid);let right = arr.slice(mid);// 递归地合并每次分割的左右数组return merge(mergeSort(left), mergeSort(right));}
}
// 把左右数组合并为一个有序数组的函数
function merge(left, right) {let result = [];let len = left.length + right.length;for (let i = 0; i < len; i++) {// 分割后左数组为空的情况if (!left[0]) {result.push(right.shift());// 右数组为空} else if (!right[0]) {result.push(left.shift());// 左右数组都不为空} else {// 较小的元素优先放入if (left[0] < right[0]) {result.push(left.shift());} else {result.push(right.shift());}}// 不存在左右数组都为空的情况,因为总循环次数为 len// 所以左右数组都空之前已经停止循环了}return result;
}

技术文章推送 手机、电脑实用软件分享

JavaScript之常见算法排序相关推荐

  1. 【数据结构Note5】- 树和二叉树(知识点超细大全-涵盖常见算法 排序二叉树 线索二叉树 平衡二叉树 哈夫曼树)

    文章目录 5.1 树和二叉树引入 5.1.1 树的概念 5.1.2 树的表示 5.1.3 树中基本术语 5.2 二叉树 5.2.1 概念 5.2.2 二叉树的性质 5.2.3 特殊的二叉树 5.2.4 ...

  2. 常见的排序算法与MSQL

    常见的排序算法 1.常见的排序算法 冒泡排序法.快速排序法.简单选择排序法.堆排序法.直接插入排序法.希尔排序法.合并排序法. (1)冒泡排序法:对待排序记录关键字从后往前(逆序)进行多遍扫描,当发现 ...

  3. access两字段同时升序排序_7 天时间,我整理并实现了这 9 种常见的排序算法

    排序算法 回顾 我们前面已经介绍了 3 种最常见的排序算法: java 实现冒泡排序讲解 QuickSort 快速排序到底快在哪里? SelectionSort 选择排序算法详解(java 实现) 然 ...

  4. JavaScript 面试中常见算法问题详解

    JavaScript 面试中常见算法问题详解,翻译自 https://github.com/kennymkchan/interview-questions-in-javascript.下文提到的很多问 ...

  5. JavaScript实现十种经典排序算法(js排序算法)

    冒泡排序算法 冒泡排序(Bubble Sort)是一种简单直观的排序算法.冒泡排序算法的步骤描述如下: 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一 ...

  6. JavaScript实现ShellSort希尔排序算法(附完整源码)

    JavaScript实现ShellSort希尔排序算法(附完整源码) Comparator.js完整源代码 Sort.js完整源代码 ShellSort.js完整源代码 Comparator.js完整 ...

  7. JavaScript实现SelectionSort选择排序算法(附完整源码)

    JavaScript实现SelectionSort选择排序算法(附完整源码) Comparator.js完整源代码 Sort.js完整源代码 SelectionSort.js完整源代码 Compara ...

  8. JavaScript实现CountingSort计数排序算法(附完整源码)

    JavaScript实现CountingSort计数排序算法(附完整源码) Comparator.js完整源代码 Sort.js完整源代码 CountingSort.js完整源代码 Comparato ...

  9. JavaScript实现topologicalSort拓扑排序算法(附完整源码)

    JavaScript实现topologicalSort拓扑排序算法(附完整源码) Comparator.js完整源代码 LinkedListNode.js完整源代码 LinkedList.js完整源代 ...

最新文章

  1. t-SNE 原理及Python实例
  2. springmvc + jquery 错误.ClassNotFoundException: org.apache.taglibs.standard.tlv.JstlCoreTLV
  3. 浏览器中唤起native app || 跳转到应用商城下载(二) 之universal links
  4. stm32f10x_it.c 定义的程序列表模板(stm32f103x_it.c中放的是中断的空函数)
  5. EMQ源码之--EMQ的启动
  6. java将数组中的数据修改,深度集成!
  7. Pipeline Alpha版本项目展示
  8. 【Spark】SparkStreaming之windows操作
  9. xml文件中删除根节点
  10. 华为 seco pc版下载_狼人之间电脑版下载-狼人之间pc版下载v1.8 官方版
  11. vuex 源码分析_Vuex源码解析(一):Module初始化
  12. 实时数据库中的二级压缩技术
  13. 在使用avalon框架的时候,用ms-duplex双工绑定,在template上是有数据渲染的,但是js里面却是undefined...
  14. Tuxedo中间件开发和管理
  15. 一个量化交易员的日常:屌丝版VS土豪版
  16. photoshop CS6 安装 coolorus色环
  17. 微信公众号如何上传html5,微信平台公众号怎么上传视频? 视频支持哪些格式
  18. epub转换mobi
  19. Programmers at Work
  20. 细粒度图像分类(FGVC)--- 综述

热门文章

  1. Innodb中的buffer poll和redo undo log
  2. (转)NSString+NSMutableString+NSValue+NSAraay用法汇总
  3. 基于Flex的迷你工作流的设计与实现(序)
  4. Cat.5e/Cat.6系统测试要点和常见工程问题解答
  5. 如何部署和搭建测试log4j 2
  6. Linux下安装ActiveMQ
  7. pytorch学习笔记(4):tensorboard可视化
  8. eclipse中配置spring约束schema
  9. php 导出excel类,php 导出excel类
  10. Java历程-初学篇 Day02变量,数据类型和运算符