博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
前端常用排序详解
阅读量:5965 次
发布时间:2019-06-19

本文共 3185 字,大约阅读时间需要 10 分钟。

排序

JS本身数组的sort方法,可以满足日常业务操作中很多的场景了。 但很多时候我们还需要知道选择排序 冒泡排序 和快速排序 的方式。

冒泡排序

文字例子:

E A D B H //原始序列A E D B H //经过一次计算(A、E交换)A D E B H //再次计算(D、E交换)A D B E H //再次计算(B、E交换)//将上面所有的循环再循环 arr.length-2次A B D E H //最终结果复制代码

动图:

代码实现

function bubleSort(arr) {    var len = arr.length;    //比较多少个循环,内部循环一次少一次    for (let outer = len ; outer >= 2; outer--) {        //前后比较,从第1个开始        for(let inner = 0; inner <=outer - 1; inner++) {            if(arr[inner] > arr[inner + 1]) {                let temp = arr[inner];                arr[inner] = arr[inner + 1];                arr[inner + 1] = temp;                //[arr2[0],arr2[1]] = [arr2[1],arr2[0]]  //这一步可用ES6解构赋值实现位置交换            }        }    }    return arr;}复制代码

选择排序

选择排序是从数组的开头开始,将第一个元素和其他元素作比较,检查完所有的元素后,最小的放在第一个位置,接下来再开始从第二个元素开始,重复以上一直到最后。

动图:

外层循环从0开始到length-1, 然后内层比较,最小的放开头,代码:

function selectSort(arr) {    var len = arr.length;    for(let i = 0 ;i < len - 1; i++) {        //从第i个开始,比较第i个和第j个的大小,小于第i个就交换,知道不小于,再累加i        for(let j = i ; j

插入排序

插入排序核心–扑克牌思想: 就想着自己在打扑克牌,接起来一张,放哪里无所谓,再接起来一张,比第一张小,放左边,继续接,可能是中间数,就插在中间….依次。

动图:

原理:

首先将待排序的第一个记录作为一个有序段。 从第二个开始,到最后一个,依次和前面的有序段进行比较,确定插入位置。

function insertSort(arr) {    for(let i = 1; i < arr.length - 1; i++) {  //外循环从1开始,默认arr[0]是有序段        for(let j = i; j > 0; j--) {  //j = i,将arr[j]依次插入有序段中进行比较,第j个大于第i个就终端换下一个            if(arr[j] < arr[j-1]) {                [arr[j],arr[j-1]] = [arr[j-1],arr[j]];            } else {                continue;            }        }    }    return arr;}复制代码

其实和冒泡排序很相似,只是将换位置放到了最后一步。

乍一看,好像插入排序速度还不慢,但是要知道: 当序列正好逆序的时候,每次插入都要一次次交换,这个速度和冒泡排序是一样的,时间复杂度O(n²); 当然运气好,前面是有序的,那时间复杂度就只有O(n)了,直接插入即可。

排序算法 平均时间复杂度 最坏时间复杂度 空间复杂度 否稳定
冒泡排序 O(n²) O(n²) O(1)
选择排序 O(n²) O(n²) O(1) 不是
插入排序 O(n²) O(n²) O(1)

还有一些更高级的排序算法,但是稳定性并不高,这里就不在写了。

递归

递归,其实就是自己调用自己。

递归步骤:

寻找出口,递归一定有一个出口,锁定出口,保证不会死循环 递归条件,符合递归条件,自己调用自己。

例子: 实现对一个对象(object)的深度克隆:

//所谓深度克隆,就是当对象的某个属性值为object或array的时候,要获得一份copy,而不是直接拿到引用值function deepClone(origin,target) {  //origin是被克隆对象,target是我们获得copy    var target = target || {}; //定义target    for(var key in origin) {  //遍历原对象        if(origin.hasOwnProperty(key)) {            if(Array.isArray(origin[key])) { //如果是数组                target[key] = [];                deepClone(origin[key],target[key]) //递归            } else if (typeof origin[key] === 'object' && origin[key] !== null) {                target[key] = {};                deepClone(origin[key],target[key]) //递归            }            target[key] = origin[key];        }    }    return target;}复制代码

这个代码不够简洁,改造一下:

function deepClone(source) {  let sourceCopy = source instanceof Array ? [] : {};  for (let item in source) {    sourceCopy[item] = typeof source[item] === 'object' ? deepClone(source[item]) : source[item];  }  return sourceCopy;}复制代码

例子:实现一个Array flat()方法,将嵌套数组扁平化。

var arr1 = [1, 2, [3, 4]];arr1.flat(); // [1, 2, 3, 4]//实现Array.prototype.flat = function() {    var arr = [];    this.forEach((item,idx) => {        if(Array.isArray(item)) {            arr = arr.concat(item.flat()); //递归去处理数组元素        } else {            arr.push(item)   //非数组直接push进去        }    })    return arr;   //递归出口}复制代码

本文中的图片来源:

转载于:https://juejin.im/post/5d08602af265da1b8811ddb4

你可能感兴趣的文章
基于 Workman 实现Web扫描登录
查看>>
karma如何与测试框架合作2之webpack
查看>>
关于VSCode更新对于emmet2.0支持的配置更改问题。
查看>>
二叉树的遍历
查看>>
三元组相加获得target
查看>>
10分钟搭建MySQL Binlog分析+可视化方案
查看>>
vmware虚拟机配置串口
查看>>
小型自动化运维--expect脚本之传递函数
查看>>
多activity中退出整个程序
查看>>
【scala初学】scala IDE eclipse
查看>>
Dockerfile构建LNMP分离环境部署wordpress
查看>>
网络中最常用的网络命令(5)-完整参数
查看>>
Exchange Server 2010部署安装之一
查看>>
Nsrp实现juniper防火墙的高可用性【HA】!
查看>>
Android 动态移动控件实现
查看>>
oracle11g 安装在rhel5.0笔记
查看>>
解决Lync 2013演示PPT提示证书问题的多种方法
查看>>
VC++动态链接库(DLL)编程(三)――MFC规则DLL
查看>>
[转]经典正则表达式
查看>>
JDBC+Servlet+JSP整合开发之26.JSP内建对象
查看>>