JavaScript之常见算法排序
文章出自个人博客 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之常见算法排序相关推荐
- 【数据结构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 ...
- 常见的排序算法与MSQL
常见的排序算法 1.常见的排序算法 冒泡排序法.快速排序法.简单选择排序法.堆排序法.直接插入排序法.希尔排序法.合并排序法. (1)冒泡排序法:对待排序记录关键字从后往前(逆序)进行多遍扫描,当发现 ...
- access两字段同时升序排序_7 天时间,我整理并实现了这 9 种常见的排序算法
排序算法 回顾 我们前面已经介绍了 3 种最常见的排序算法: java 实现冒泡排序讲解 QuickSort 快速排序到底快在哪里? SelectionSort 选择排序算法详解(java 实现) 然 ...
- JavaScript 面试中常见算法问题详解
JavaScript 面试中常见算法问题详解,翻译自 https://github.com/kennymkchan/interview-questions-in-javascript.下文提到的很多问 ...
- JavaScript实现十种经典排序算法(js排序算法)
冒泡排序算法 冒泡排序(Bubble Sort)是一种简单直观的排序算法.冒泡排序算法的步骤描述如下: 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一 ...
- JavaScript实现ShellSort希尔排序算法(附完整源码)
JavaScript实现ShellSort希尔排序算法(附完整源码) Comparator.js完整源代码 Sort.js完整源代码 ShellSort.js完整源代码 Comparator.js完整 ...
- JavaScript实现SelectionSort选择排序算法(附完整源码)
JavaScript实现SelectionSort选择排序算法(附完整源码) Comparator.js完整源代码 Sort.js完整源代码 SelectionSort.js完整源代码 Compara ...
- JavaScript实现CountingSort计数排序算法(附完整源码)
JavaScript实现CountingSort计数排序算法(附完整源码) Comparator.js完整源代码 Sort.js完整源代码 CountingSort.js完整源代码 Comparato ...
- JavaScript实现topologicalSort拓扑排序算法(附完整源码)
JavaScript实现topologicalSort拓扑排序算法(附完整源码) Comparator.js完整源代码 LinkedListNode.js完整源代码 LinkedList.js完整源代 ...
最新文章
- t-SNE 原理及Python实例
- springmvc + jquery 错误.ClassNotFoundException: org.apache.taglibs.standard.tlv.JstlCoreTLV
- 浏览器中唤起native app || 跳转到应用商城下载(二) 之universal links
- stm32f10x_it.c 定义的程序列表模板(stm32f103x_it.c中放的是中断的空函数)
- EMQ源码之--EMQ的启动
- java将数组中的数据修改,深度集成!
- Pipeline Alpha版本项目展示
- 【Spark】SparkStreaming之windows操作
- xml文件中删除根节点
- 华为 seco pc版下载_狼人之间电脑版下载-狼人之间pc版下载v1.8 官方版
- vuex 源码分析_Vuex源码解析(一):Module初始化
- 实时数据库中的二级压缩技术
- 在使用avalon框架的时候,用ms-duplex双工绑定,在template上是有数据渲染的,但是js里面却是undefined...
- Tuxedo中间件开发和管理
- 一个量化交易员的日常:屌丝版VS土豪版
- photoshop CS6 安装 coolorus色环
- 微信公众号如何上传html5,微信平台公众号怎么上传视频? 视频支持哪些格式
- epub转换mobi
- Programmers at Work
- 细粒度图像分类(FGVC)--- 综述
热门文章
- Innodb中的buffer poll和redo undo log
- (转)NSString+NSMutableString+NSValue+NSAraay用法汇总
- 基于Flex的迷你工作流的设计与实现(序)
- Cat.5e/Cat.6系统测试要点和常见工程问题解答
- 如何部署和搭建测试log4j 2
- Linux下安装ActiveMQ
- pytorch学习笔记(4):tensorboard可视化
- eclipse中配置spring约束schema
- php 导出excel类,php 导出excel类
- Java历程-初学篇 Day02变量,数据类型和运算符