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

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

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

1.冒泡排序

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

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

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

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

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

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

2.鸡尾酒排序

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

核心代码如下:

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

耗费时间如下

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

3.选择排序

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

代码如下:

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

花费时间如下:

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

4.插入排序

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

代码如下:

function InsertionSort(arr) {
console.time('timer');
for (let i = 1; i < arr.length; i++) {
for (let j = i; j > 0 && arr[j] < arr[j - 1]; j--) {
[arr[j], arr[j - 1]] = [arr[j - 1], arr[j]];
}
}
console.timeEnd('timer');
}

同数组耗时如下:

总结:在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. Sublime Text 执行后只有运行时间,没有执行结果!解决方法!

    问题:build完python代码,只输出:[Finished in 0.2s] 分析:操作回忆:开始是可以看到运行结果的,后来在Tools>>Build with 选择了"Sy ...

  2. 数据结构树之AVL树(平衡二叉树)

    一 什么是AVL树(平衡二叉树): AVL树本质上是一颗二叉查找树,但是它又具有以下特点:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树.在AVL树中任何节 ...

  3. return this 和return * this

    this是指向自身对象的指针,*this是自身对象. 也就是说return *this返回的是当前对象的克隆或者本身(若返回类型为A, 则是克隆, 若返回类型为A&, 则是本身 ). retu ...

  4. 面试简单整理之Redis

    179.redis 是什么?都有哪些使用场景? Redis是一个key-value存储系统. 缓存,消息队列,排行榜/计数器,分布式架构,做session共享 180.redis 有哪些功能? 181 ...

  5. 20172306 2018-2019-2 《Java程序设计与数据结构》第七周学习总结

    20172306 2018-2019-2 <Java程序设计与数据结构>第七周学习总结 教材学习内容总结 概述 二叉查找树是一种含有附加属性的二叉树,即其左孩子小于父结点,而父结点又小于或 ...

  6. 安卓adb工具的安装方法

    adb是Android的一个很重要的调试工具,熟练掌握后可实现很多功能,比如有些手机的解锁.ROOT就会用到adb工具.可很多朋友都说不会安装,今天就从最开始的安装方法说起. adb工具其实不用安装, ...

  7. 将bean转换成XML字符串

    package com.sinoservices.bms.bbl.rest.bean; import javax.xml.bind.annotation.XmlAccessType; import j ...

  8. 《修炼之道:.NET开发要点精讲》读书笔记(三)

    后几章的习题 1.异步调用开始后,什么时候才能使用异步执行的结果? A:最好在EndInvoke()方法返回之后才能使用异步执行的结果,其它时候不能保证异步调用已完成. 2.委托的异步调用开始后(即调 ...

  9. C# 互通操作 (一)

    回顾一下自己学习的内容然后从互通的基础案例开始写起. 这次实现一个很简单的互通demo,就是 在unity里  在c#里调用windows窗体的MessageBox 消息提示 public class ...

  10. 关于numpy.maximum函数的测试

    atr.py import numpy as np a = np.arange(9)print("a:",a)print(a[0:3])print(a[3:6])print(a[6 ...