前端不懂算法(二)--插入排序,选择排序

java冒泡、选择、插入排序 本文介绍了三种基础排序算法:冒泡排序、选择排序和插入排序。冒泡排序通过相邻元素比较交换将最大值"冒泡"到末尾;选择排序每次选择未排序部分的最小值放入已排序区;插入排序则将元素逐个插入已排序部分的正确位置。三种算法均为原地排序,时间复杂度在O(n)到O(n²)之间,适用于小规模数据。冒泡和插入排序稳定,而选择排序不稳定。文章通过Java代码示例展示了各算法的实现原理和特点。 阅读详情

审核大哥,这篇文章是介绍前端实现排序算法,是很常见的IT知识,题目是对前端行业的调侃。善意的,友好的,符合 新时代思想文化建设的。

本篇文章参考借鉴了以下文章和极客时间数据结构与算法一文,若涉及侵权,请联系我删除。

前言

上一篇文章是关于冒泡排序的学习总结,还未学习的同学可以先看一下以下文章

本节我们一期学习一个新的排序算法,插入排序

带着问题学习

  首先需要思考,一个有序的数组,在往里面插入一个新的数据之后,如何保持数据有序呢?很简单,我们只需要遍历数据,找到数据应该插入的地方,将其插入即可。
在这里插入图片描述
  这是一个动态排序的过程,即动态的往有序集合里添加数据,我们可以通过这种方式,保持集合中的数据一直有序。而对于一组静态数据,我们也可以借鉴上面的插入方法,来进行排序,于是就有了插入排序。

插入排序是如何借助动态思想,实现排序的?

  受限,我们将数组中的数据分为两个区域,已排序区域和未排序区域。初始已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想就是 取未排序区间的元素,在已排序区间中找到合适的位置将其插入,并保证已排序区间的数据,一直有序 。重复这个过程,直到未排序区间为空,算法结束。

  如下图所示,要排序的数据是4、5、6、1、3、2,其中左侧为已排序区间,右侧是未排序区间。

在这里插入图片描述
  插叙排序也包含两种操作,一种是 元素的比较 ,一种是 元素的移动 。当我们需要讲一个数据 a 插入到已排序区间时,需要拿 a 与已排序区间的元素依次比较大小,找到合适的插入位置。

  找到插入点后,我们还需要把插入点之后的元素顺序往后移动一位,这样才能腾出位置给 a 元素插入。

  对于不同的查找插入点的方法(从头到尾,从尾到头),元素的比较次数是有区别的,但对于一个给定的初始序列,移动操作次数总是固定的。就等于 逆序度。

  为什么说义移动次数就等于逆序度呢?把上面的例子做一个分析就一目了然了
在这里插入图片描述
  满有序度是 n*(n - 1)/2 = 15,初始序列的有序度是 5 ,所以逆序度是 10 ,插入排序中,数据移动总和等于 10 = 3+3+4。(可以参考上一篇文章 )-- 前端不懂算法(一)–冒泡排序

代码实现

function insertSort(arr) {
    let n =  arr.length;
    if (n<=1) return;
    
    for (let i = 1; i < n; ++i) {

        let value = arr[i];
        let j = i - 1;

        //查找插入位置
        for (; j >= 0; --j) {
            if (arr[j] > value) {
                //数据移动
                arr[j + 1] = arr[j]
            } else {
                break;
            }
        }
        //插入数据
        arr[j+1] = value;
    }
}

Q&A,排序算法的三个问题

第一,插入排序是原地排序算法吗?

  从实现过程可以看出,插入排序算法的运行并不需要额外的存储空间,所以空间复杂度是 O(1),也就是说,这是一个 原地排序算法。

第二,插入排序是稳定的排序算法吗?

  在插入排序中,对于值相等的元素,我们可以选择将后面出现的,插入到前面出现元素的后面,这样就可以保证原有的前后顺序不变,所以插入排序是稳定的排序算法。

第三,插入排序的时间复杂度是多少?

  如果要排序的数据已经是有序的,我们并不需要搬移任何数据。如果我们从尾到头在有序数据组里面查找插入位置。每次只需要比较一个数据就能确定插入位置。所以这种情况下,最好的时间复杂度为O(n)。

  如果数组是倒序的,每次插入都相当于在数组的第一个位置插入数据,需要移动大量的数据,所以最坏情况的时间复杂度为O(n2)。

还记得最开始我们讨论的,在数组中插入一个数据的平均时间复杂度是多少吗?没错就是O(n),所以对于插入排序来说,每次插入都相当于在数组中插入一个数据,循环执行 n 次插入操作,所以平均时间复杂度为O(n2)。

选择排序

  选择排序的实现方式有点类似于插入排序,也分已排序区间和未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。
在这里插入图片描述

选择排序的三个问题

  照例,思考三个问题,前面的解释已经很详细了,这里就直接公布答案。

  选择排序的控件复杂度为O(1),是一种原地排序算法。选择排序的最好情况、最坏情况和平时情况时间复杂度都为O(n2)。有兴趣的同学可以自己分析一下。

  选择排序是稳定的排序算法吗?这个问题需要重点讨论。

  答案是否定的,选择排序是一种不稳定的排序算法。从前面那张图可以看出,选择排序每次都要找出剩余未排序元素中的最小值,然后和前面的元素交换位置,这样就破坏了稳定性。

比如5、8、5、2、9 这组数据,使用选择排序的话,第一次选择 2 ,与第一个 5 交换位置,那么这两个 5 的前后顺序就变了,所以不稳定。正因如此,相对于冒泡排序和插入排序,选择排序就稍稍逊色一些。

排序系列开篇问题

  我在本系列开篇的地方了一个问题,为什么插入排序比冒泡排序更受欢迎?如果不记得的同学可以查看上一篇博文

  我们已经学习了三种排序,其中冒泡排序和插入排序的时间复杂度都是 O(n2)。都是原地排序算法,为什么插入排序比冒泡排序更受欢迎?

  因为之前我们说过,冒泡排序不管怎么优化,其元素交换的次数是一个固定值,是原始数据的逆序度。插入排序也是一样的,不管怎么优化,元素移动的次数也是逆序度。

  但是,从代码实现上来看,冒泡排序的数据交换,要比插入排序的数据移动复杂的多,冒泡需要三个赋值,而插入只需要一个,下面是代码部分:

if (arr[j] > arr[j + 1]) {
  let temp = arr[j];
    arr[j] = arr[j + 1];
    arr[j + 1] = temp;

    //表示有数据交换
    flag = true;
}
if (arr[j] > value) {
	//数据移动
    arr[j + 1] = arr[j]
} else {
    break;
}

  我们把执行一个赋值语句的时间记做单位时间 unit ,然后分别用冒泡排序和插入排序对同一个逆序度是 K 的数组进行排序。用冒泡排序,需要 K 次交换,每次需要三个赋值语句,所以交换操作总耗时就是 3*K unit 而插入排序排序中移动操作只需要 K 个单位时间。

  这个只是理论的推测,大家可以分别用两个方法对一个数组进行排序,计算一下算法执行时间,我以前做过一个随机生成1000个数组,每个数组包含200个数据的实验,冒泡排序大概需要 700ms , 而插入排序只需要 100ms 就能搞定。

当然插入排序也是可以进一步优化的,具体方法可以学习一下 希尔排序。

内容小结

  想要分析,评价一个排序算法,需要从执行效率,内存消耗,稳定性三个方面考虑。因此这一节中,我们分析了三种,时间复杂度为 O(n2) 的排序算法
在这里插入图片描述
  上面三种算法中,冒泡排序,选择排序,基本都是停留在理论层面,了解一下,拓展一下思路,实际开发中运用的并不多,但是插入排序还是很有用的,后面讲排序优化的时候,会讲到有些编程语言中的排序函数,就是使用的插入排序算法。

  本文这几个排序算法,代码简单,比较适合小型排序,用起来也很高效。但是在大规模数据排序的时候,时间复杂度还是有点高,需要倾向于下一节的时间复杂度为 O(nlogn)的排序算法。

  文中不足之处,请各位大佬指点。

前端面试题目整理——排序算法 https://forrany.github.io/2018/08/21/2018-08-21-front-end-interview-algorithm/ https://blog.youkuaiyun.com/github_36673034/article/details/79323198 https://blog.youkuaiyun.com/weixin_38984353/article/details/8039... 阅读详情

相关推荐

新手入门机器学习案例(附源代码)

无

guguo666的博客 6655

前端JS算法--插入排序

插入排序的时间复杂度是 O(n^2),在数据规模较小或部分数据已经有序的情况下效率较高。对于大型数据集,插入排序通常不如更高级的排序算法,如快速排序、归并排序或堆排序。不过,插入排序是稳定的排序算法,且在某些情况下,如数据已经部分有序,它的实际性能可能比理论时间复杂度要好。插入排序(Insertion Sort)是一种简单直观的排序算法,它的工作原理是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增加1的有序表。

CC酱写前端的博客 479

用AI助手Cursor轻松自动生成流程图

通过 Cursor + Mermaid,我们可以快速、准确地自动生成流程图,上面演示的例子部分流程图可能比较丑,我们可以通过流程图软件导入Mermaid代码,然后手动进行微调就可以了,如果你对美观要求不是特别多,可以直接用,这将极大地提升代码可视化和架构设计的效率。

呱牛 Just do IT 1936

前端算法--插入排序

插入排序总结

qq_66349348的博客 212

MySQL安装配置教程(超级详细)

一、 下载MySQL Mysql官网下载地址:MySQL :: Download MySQL Installer (Archived Versions) 1. 选择要安装的版本,本篇文章选择的是5.7.31版本,点击Download下载 正在上传…重新上传取消 二、 安装MySQL 1. 选择设置类型双击运行mysql-installer-community-5.7.31.0.msi 这里选择是自定义安装,所以直接选择“Custom”,点击“Next” “Developer Default”是

m0_67322837的博客 5万+

MacOS多次踩坑后成功安装Homebrew

来一次性成功安装Homebrew吧 官网提供的安装脚本无法成功安装Homebrew,原因大家都懂的,故采用脚本安装的方式。 下载homebrew的安装脚本brew_install 在Download路径下执行如下脚本 curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install >> brew_install 修改brew_install脚本 修改brew_install脚本。如果你的脚本打开之后是如下

weixin_41847116的博客 1981

排序算法之---插入排序(看完不懂来打我呀呀)

一、插入排序 还是那句话:不是常用的我不说,实用才是王道。 算法基本思想: 一个未排序的数组(也可以是链表)可以分为两个部分,前半部分是已经排序的,后半部分是未排序的。 在进行未排序时,只需要在未排序的部分中选择一个元素,将其插入到前面有序的数组中即可(找到合适的位置插入) 直到未排序的为0,则排序完成。 二、直接上代码:(会的就不用看第三部分了) Java老大哥: package suanF...

qiukui111的博客 412

Oracle Patch清理

- opatch clean的帮助,该命令清除.patch_storage directory文件夹下的'restore.sh,make.txt' files and 'scratch,backup'-- 执行完毕后,貌似没有变化,可能和自己环境有关(19年开始测试补丁,基本上每个季度都测试,后面把又把数据库用RMAN做了迁移,又转换成了PDB模式)。在对Oracle安装补丁后,会发现OS上被占用了大量的空间,本文档清理Opatch过程中的一些文件,释放空间。--清理后空间,剩余25G。

文档搬运工 1072

js实现的插入排序算法

插入排序js实现

前端小白菜 572

Openbmc系列之自动化测试框架1

Openbmc作为当下BMC固件领域最流行的开源软件,具备从需求计划、开发、调试、测试、版本管理等完整的体系。在测试领域,Openbmc基于python的robotframework框架,实现Openbmc的自动化测试,为高效发布Openbmc版本提供有力支持。本文作为测试系列文档一,介绍Openbmc自动化测试虚拟Openbmc的环境搭建。

qq_20341747的博客 2109

Keil开发中CMSIS Driver API缺失问题的排查与解决

本文详细解析Keil开发中CMSIS Driver API缺失问题的根源与解决方案。针对版本不匹配、安装不完整等常见原因,提供在线与离线安装的对比及详细排查步骤,重点涵盖版本兼容性分析与项目配置验证,帮助开发者彻底解决API缺失错误并预防问题复发。

rust6ferris的博客 550

经典算法之直接插入排序(三种实现)

直接插入排序(Insertion Sort)的基本思想是:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的子序列中的适当位置,直到全部记录插入完成为止。设数组为a[0…n-1]。 1. 初始时,a[0]自成1个有序区,无序区为a[1..n-1]。令i=1 2. 将a[i]并入当前的有序区a[0…i-1]中形成a[0…i]的有序区间。 3. i++并重复

进击的程序猿 4967

HyperLynx(十九)DDR(二)DDR的地址仿真

(5)设置水平标尺为2ns/div,垂直标尺为500mV/div,如果有必要,可以通过多次仿真,得到一个更加理想的结果。此外,还可以看到信号在高低电平切换时,反射波形基本趋于平缓,许多大的反射切换边缘已减小,这给了我们更大的定时裕量。如果这些DIMM是缓冲过的,则4个DIMM通道是可行的,但因为这是一个无缓冲DIMM,(20)在编辑传输线对话框中,选择“Values”选项卡,改变传输线长度为3in,具体设置如图所示,单击“确定”按钮。(17)为了增加电压摆幅,选择一个比原来的47Ω小的电阻。

小幽余生不加糖 4257

【数据结构与算法】简单排序(冒泡排序、选择排序、插入排序)完整思路,并用代码封装排序函数

之前的文章,我已经把前端需要了解的数据结构都给说了一边,并且我们也都对其进行了封装。现在我们要开始对排序算法部分进行讲解,排序算法顾名思义,就是对一堆杂乱无章的数据按照一定的规则将它们有序地排列在一起。 在讲解排序算法时,大致分成两大类,如下图 本文

零一的博客 2万+

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

前端经典算法之冒泡排序-选择排序-插入排序

前端经典算法之冒泡排序-选择排序-插入排序1、冒泡排序 算法步骤js代码实现2、选择排序1. 算法步骤js代码实现3、插入排序1. 算法步骤js 代码实现 1、冒泡排序 冒泡排序 (Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。 +算法步骤 比较相邻的元素。如果第一个比第二个大,就交换他们两个。 对每一对相邻元素作同样的工作,从开始第一对到结尾的

qq_45094682的博客 2455

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

常见的五种排序,冒泡排序,选择排序,插入排序,并归排序,快速排序

冒泡排序 冒泡排序介绍: 冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。 它重复地跑过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小)那么它就会按照大到小的排序方式来。它必须要把算所有的元素重复地进行跑一遍,直到没有相邻元素需要交换,也就是说该元素列已经排序完成。 冒泡排序算法的原理如下: 1,比较相邻的元素。如果第一个比第二个大,就交换他们两个,如果不是相等的就跳过比下面的元素 ,这样依次的循环下去 直到所有的元素都比较完成才结束。 2,针对所有的元素重复以上的

无心 2622

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

前端必须掌握的五种排序算法,你会几种?

在前端开发中,对数据进行排序是一项基本且常见的任务。掌握排序算法不仅可以帮助我们更有效地处理数据,还能提升代码的执行效率。冒泡排序、选择排序、插入排序、快速排序和归并排序。通过理解这些算法的原理和逻辑,我们可以更好地选择合适的排序方法来优化应用性能。正文开始💖💖💖。

前端探索者 3753

【总结】:大厂面试常考手撕代码 —— JavaScript排序算法(冒泡排序、选择排序、插入排序、快速排序)

文章目录1. 冒泡排序2. 选择排序3. 插入排序4. 快速排序 1. 冒泡排序 //冒泡排序 let arr = [2, 4, 1, 6, 3] function bubbled(arr) { for (let i = 0; i < arr.length - 1; i++) { //【!!注意】这里不是j=i,因为回回都必须重头遍历,才能不漏一个嘛~ for (let j = 0; j < arr.leng.

weixin_60297362的博客 6466

前端不懂算法(一)--冒泡排序

本篇文章参考借鉴了叶老师的数据结构与算法一文,若涉及侵权,请联系我删除。 文章目录前言如何分析一个“排序算法”?排序算法的执行效率1.最好情况,最坏情况,平均情况时间复杂度2.时间复杂度的系数,常数,低阶3.比较次数和交换(或移动)次数排序算法的内存消耗排序算法的稳定性冒泡排序Q1,冒泡排序是原地排序吗?Q2,冒泡排序是稳定的排序算法吗?Q3,冒泡排序的时间复杂度是多少? 前言   对于大多数人来...

不见浅诗的博客 902

前端排序算法,冒泡排序、插入排序、快速排序、选择排序

1.冒泡排序思想:数组当前项和后一项比较,前比后大则交换位置,最大的数放后面。 以下代码实现: function bubbleSort(arr){ let temp = null; var len = arr.length; for(let i=0; i<len-1; i++){ for(let j=0; j<len-1-i; j++){ ...

weixin_44143279的博客 465

前端数组排序冒泡排序;选择排序;插入排序

冒泡排序:重复访问数列,一次比较相邻两个元素,如果前一个元素比后一个元素大,那么交换他们的顺序,多次交换之后得出正确排序。 假设有这样一个数组[7, 3, 6, 1, 9, 2, 5, 4, 0, 8],使用冒泡排序进行排序,每次循环从最后一个元素开始,相邻的两个元素进行比较,如果前一个元素大于后一个元素,则两者互换 第一次排序的结果为[7, 3, 6, 1, 9, 2, 5, 4, 0, ...

Sunny_lxm的博客 555

JS实现简单排序 ——(冒泡排序、选择排序、插入排序)

在前端面试,对数据结构与算法的要求不多,但是排序是必须掌握的,在笔试、面试中经常考到或者提问。在此,我从JS实现了排序中的简单排序——冒泡排序、选择排序、插入排序,并且比较他们的效率。

weixin_43324314的博客 1212

raptor输入n个数据排序_面试官问选择排序和插入排序时,你可不要搞混了

选择和插入都是比较简单的排序算法.两种算法都是通过将最小值前移的方式进行排序的.不同的是插入排序是取i值和i前面的数据做逐一比较,将最小值放在最前端,而选择排序是将i后面的最小值和i位置进行交换.下面具体说一下两种算法的区别选择排序其排序流程如下:首先从原始数组中选择最小的一个数据,将其和位于第一个位置的数据进行交换。接着从剩下的 n-1 个数据中选择次小的一个元素,将其和第二个位置的数据交换。然...

weixin_39831991的博客 2046

排序算法大比拼:冒泡排序、选择排序和插入排序,谁更胜一筹?

冒泡排序:简单易懂,适合学习和小规模数据,但性能较差。选择排序:虽然优化不明显,但相对简单;对于数据较少时效率较高。插入排序:在小规模数据时表现良好,尤其是当数据基本有序时,效率极高。以上方法都适合用于小数据集的排序。在实际应用中,对于大规模数据,通常会使用更高效的排序算法,如快速排序或归并排序。

你若盛开,清风自来 1058

【面试必备】前端常见的排序算法

现在越来越多的公司都会考察前端程序员的算法能力了,所以我们有必要去学习一下前端常见算法的基本思想。

南玖的博客 1273
上一篇: 前端不懂算法(一)--冒泡排序
下一篇: 前端不懂算法(三)--归并排序
不见浅诗~
博客等级 码龄7年 506粉丝 129原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值