作为一个有追求的前端,忙里偷闲(闲得发慌)地复习了一下基础的排序算法,以此文留念.

本篇主要记录O(n²)复杂度的基础算法O(nlogn)的算法将在下次有空(闲得发慌)时更新

在记录时发现Es6语法中的解构赋值与传统的中间变量交换相比效率低下,经过几次测试发现其耗时大约为交换中间变量的两倍

1.冒泡排序

众所周知排序最基础的算法,也就是大名鼎鼎的冒泡了,为了方便日后回顾还是简单提一下冒泡的原理:

其核心思想在于不停地比较相邻元素的大小关系,如果前面的比后面的大则两个元素互换位置(此处以顺序为例);每当一次大的循环后总能将当前剩余数中最大的数交换到数组的末尾,类似于一个泡泡从底部浮出水面,故得名冒泡算法.下方代码为未使用任何优化的原始冒泡算法.

其时间复杂度为O(n²) 不需要额外空间;

  1. //冒泡排序
  2. function BubbleSort(arr) {//arr即需要排序的数组;本文后续中的arr均为此意
  3. console.time('timer');//用于统计代码执行时间
  4. for (let i = 0; i < arr.length; i++) {
  5. for (let j = 0; j < arr.length; j++) {
  6. if (arr[j] > arr[j + 1])
  7. [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];//交换元素(解构赋值ES6)
  8. }
  9. }
  10. console.timeEnd('timer');
  11. }

以一万个数构成的倒序(从大到小)数组变为顺序的时间如下图(与个人电脑及其它因素有关请勿较真)用解构赋值交换:

后续算法的时间均以同一数组测试

2.鸡尾酒排序

这种排序算法乃是对冒泡算法的一种小优化,其与冒泡的区别在于,在一趟排序中可以将一个最大的移到后端,同时将一个最小的移到前端,从而对冒泡算法进行优化

核心代码如下:

  1. //鸡尾酒排序
  2. function CocktailSort(arr) {
  3. console.time('timer');
  4. let [start, end] = [0, arr.length];
  5. while (start < end) {
            //此循环与正常冒泡一致
  6. for (let i = start; i < end; i++) {
  7. if (arr[i] > arr[i + 1])
  8. [arr[i], arr[i + 1]] = [arr[i + 1], arr[i]];
  9. }
  10. end--;//由于数组最后一位已经是最大的所以没有必要再让其参与后续的排序
  11. for (let i = end - 1; i >= start; i--) {
  12. if (arr[i] < arr[i - 1])
  13. [arr[i], arr[i - 1]] = [arr[i - 1], arr[i]];
  14. }
  15. start++;
  16. }
  17. console.timeEnd('timer');
  18. }

耗费时间如下

由于其本质与冒泡算法类似,虽然好上些许,但其本质仍为O(n²)的时间复杂度故时间并未得到太大的缩减(由于解构赋值的原因优化后的算法还不如不优化,是真的骚)

3.选择排序

选择排序也是大家所熟知的一种基础算法,其核心在于每一次选出最小(或最大)的一个数放到已经有序的数列后,经过如此重复操作后获得有序的数列

代码如下:

  1. //选择排序
  2. function SelecttionSort(arr) {
  3. console.time('timer');
  4. for (let i = 0; i < arr.length; i++) {
  5. let min = i;//min表示当前最小值的下标
  6. for (let j = i + 1; j < arr.length; j++) {
  7. min = arr[j] < arr[min] ? j : min; //如果当前下标的值比arr[min]的值要小则以当前值替换
  8. }
  9. [arr[i], arr[min]] = [arr[min], arr[i]];
  10. }
  11. console.timeEnd('timer');
  12. }

花费时间如下:

按理说同为n平方的复杂度时间耗费应该相差不大才对,结果由于交换次数的减少导致耗时大幅下降,感觉Js在这方面效率有点低

4.插入排序

插入排序的原理为将当前下标的数插入之前已经有序的数列中,从后往前遍历找到合适的位置后将值插入,并将该位置之后的元素依次后移从而进行排序

代码如下:

  1. function InsertionSort(arr) {
  2. console.time('timer');
  3. for (let i = 1; i < arr.length; i++) {
  4. for (let j = i; j > 0 && arr[j] < arr[j - 1]; j--) {
  5. [arr[j], arr[j - 1]] = [arr[j - 1], arr[j]];
  6. }
  7. }
  8. console.timeEnd('timer');
  9. }

同数组耗时如下:

总结:在Js的情况下交换数据应尽量少的使用解构赋值,虽然其便利性很强,但是当网页对性能要求较高时应减少解构赋值的使用,如果非用不可,在同等级时间复杂度算法的情况下应使用数字交换次数少的算法以提升页面性能

JavaScript 基础排序的实现(一)的更多相关文章

  1. JavaScript 基础排序的实现(二)

    继上一篇O(n^2)的排序算法后,这一篇主要记录O(n*logn)的排序算法 1.快排(快速排序) 这一算法的核心思想为,先随机选一个数作为标兵或者说是标记(这个数一般来说选择该无序数组的中间那个元素 ...

  2. JavaScript基础

    JavaScript基础 JavaScript是一门编程语言,浏览器内置了JavaScript语言的解释器,所以在浏览器上按照JavaScript语言的规则编写相应代码之,浏览器可以解释并做出相应的处 ...

  3. 前端之JavaScript基础

    前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript历史 1992年Nombas开发出C ...

  4. 一步步学习javascript基础篇(3):Object、Function等引用类型

    我们在<一步步学习javascript基础篇(1):基本概念>中简单的介绍了五种基本数据类型Undefined.Null.Boolean.Number和String.今天我们主要介绍下复杂 ...

  5. javascript基础部分

    javascript基础部分 1  数据类型: 基础数据类型(通过typeof来检测):Number,string,undefined,null,boolean,function typeof只能检测 ...

  6. 《JavaScript基础教程(第8版)》PDF

    简介:JavaScript基础教程(第8版)循序渐进地讲述了JavaScript及相关的CSS.DOM.Ajax.jQuery等技术.书中从JavaScript语言基础开始,分别讨论了图像.框架.浏览 ...

  7. JavaScript基础笔记二

    一.函数返回值1.什么是函数返回值    函数的执行结果2. 可以没有return // 没有return或者return后面为空则会返回undefined3.一个函数应该只返回一种类型的值 二.可变 ...

  8. 第三篇:web之前端之JavaScript基础

    前端之JavaScript基础   前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript ...

  9. javascript基础、语法

    JavaScript基础(简介.语法) 一.JavaScript简介 1.JavaScript是个什么东西? 它是个脚本语言,需要有宿主文件,它的宿主文件是HTML文件. 2.它与Java什么关系? ...

随机推荐

  1. 【Rails App】 应用服务器从Passenger切换为Puma, Grape出现线程安全问题

    Grape中的代码如下: def market @market ||= Market.find(params[:id]) end @market基于类层次的实例变量,属于非线程安全,如果一直使用多线程 ...

  2. Spring整合quartz关闭,关闭Tomcat Servlet容器时内存泄漏

    出错信息 22-Sep-2017 06:19:51.064 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearR ...

  3. echarts - 条形图grid设置距离绘图区域的距离

    在一些数据量过大的情况下,在一个固定的区域绘图往往需要对图表绘制区域的大小进行动态改变.这时候设置条形图距离绘图区域上下左右的距离可使用如下方式:表示条形图的柱子距离绘图区左边30%,距离右边40%, ...

  4. 谷歌搜索技巧(转)https://www.runningcheese.com/google

    原文地址: Google是一个非常精密成熟的搜索引擎,其搜索结果的丰富性和准确度较其他搜索引擎都要好,但大多数用户都还只是停留在搜索框中输入一两个关键字,然后点击“搜索”按钮的阶段,这一过程是非常低效 ...

  5. python 数据库mysql、redis及发送邮件

    python 关系型数据库链接使用--mysql import pymysql # 引用mysql模块 # 创建连接,指定数据库的ip地址,账号.密码.端口号.要操作的数据库.字符集coon = py ...

  6. 20170529计划---统计业务量并生成EXCEL通过邮件发送

    每个月都要统计这些业务量的东东,烦死了,赶紧通过python写一个来搞定吧,三天搞定吧,未完待续哈. 2017-5-29 19:50粗略地做了一个思维导图哈 终于第三天完成啦 #encoding=ut ...

  7. delphi中 panel如何在Form实现鼠标移动拖放

    Panel的MouseDown事件 移动就写上ReleaseCapture;SendMessage(Panel1.Handle,wm_SysCommand,$F012,0); 改变大小就写上Relea ...

  8. IDEA高效运用技巧

    windows: //快捷鍵 1.项目之间的切换快捷键:Ctrl+Alt+[]. 2.文件之间切换快捷键:Ctrl+Alt+左右箭头. 3.返回到上一次修改的地方:Ctrl+Q. 4.查找打开过的文件 ...

  9. AngularJS入门-demo

    双向绑定测试: <body ng-app> 请输入姓名:<input ng-model="myname"> <br> {{myname}},你好 ...

  10. Golang之路【目录】

    我正在写一套使用Golang全栈开发的教程,名字暂叫“Golang之路”,希望大家多提建议. 目录如下: Golang之路[第一篇]:Golang简介和入门Golang之路[第二篇]:Golang基础 ...