【学习笔记31】JavaScript冒泡排序和选择排序

news2025/7/6 20:43:16

笔记首发

一、冒泡排序

在这里插入图片描述

(一)核心原理

  • 循环遍历数组,当前单元和下一个单元进行数据比较
  • 按照从小到大排序,应该是当前单元小于下一个单元,如果当前单元大于下一个单元,将交换两个单元存储的数据
  • 一次循环结束,会将一个最大值存储到数组末位
  • 多次循环遍历,完成整个数组中数值的排序

(二)执行步骤

1、第一步:完成一次排序*

        // 定义一个数组 
        const arr = [9, 5, 6, 8, 2, 7, 3, 4, 1];
        console.log('原始数组:', arr );

        // 循环遍历数组 循环遍历一次会将一个最大值存储到数组末位
        for( let i = 0 ; i < arr.length ; i++ ){
            // i 是当前单元索引下标   arr[i] 是当前单元数据数值
            // i+1 是下一个单元索引下标  arr[i+1] 是下一个单元数据数值

            // 如果当前单元数据数值大于下一个单元数据数值,即arr[i]大于arr[i+1]
            // 交换两个单元存储的数据数值
            if( arr[i] > arr[i+1] ){
                // 利用中间变量交换两个单元存储的数据
                let temp = arr[i];
                arr[i] = arr[i+1];
                arr[i+1] = temp;
            }
        }
        console.log('交换第一次之后的数组:', arr );

在这里插入图片描述

2、多次执行排序

  • 循环遍历一次,将一个最大值排序到数组末位
  • 多次执行排序操作,完成整个数组的排序
        // 定义一个数组 
        const arr = [9, 5, 6, 8, 2, 7, 3, 4, 1];
        console.log('原始数组:', arr );

        // 通过外层循环多次执行 内层循环完成整个数组的排序
        for (let j = 0; j < arr.length; j++) {

            // 循环遍历数组 循环遍历一次会将一个最大值存储到数组末位
            for( let i = 0 ; i < arr.length ; i++ ){
                    // i 是当前单元索引下标   arr[i] 是当前单元数据数值
                    // i+1 是下一个单元索引下标  arr[i+1] 是下一个单元数据数值

                    // 如果当前单元数据数值大于下一个单元数据数值,即arr[i]大于arr[i+1]
                    // 交换两个单元存储的数据数值
                    if( arr[i] > arr[i+1] ){
                        // 利用中间变量交换两个单元存储的数据
                        let temp = arr[i];
                        arr[i] = arr[i+1];
                        arr[i+1] = temp;
                    }
                }
        }
        console.log('多次循坏后的数组:', arr );

在这里插入图片描述

3、代码程序的优化

外层优化

  • 最后一个单元没有单元进行数据比较
  • 即n个单元只需要循环n-1次就可以完成排序

内层优化

  1. 当前单元和下一个单元进行数据比较,最后一个单元没有下一个单元进行数据比较
    内层循环是从数组的第一个单元循环至循环的倒数第二个单元
  2. 上一次排序排序出最大值, 不参与 下一次的循环排序
    第一次是 1-9 单元排序 少排序0个单元
    第二次是 1-8 单元排序 少排序1个单元
    第三次是 1-7 单元排序 少排序2个单元
    第四次是 1-6 单元排序 少排序3个单元
    .....
    少排序的单元个数 0 1 2 3 4... 
    正好对应外层循环变量的数值
    
        // 定义一个数组 
        const arr = [9, 5, 6, 8, 2, 7, 3, 4, 1];
        console.log('原始数组:', arr);

        // j <= arr.length-1:外层循环是循环次数n个单元循环n-1次 
        for (let j = 0; j < arr.length - 1; j++) {

            /*  
                i <= arr.length -1 
                    最后一个单元没有和下一个单元进行数据比较 
                    只需要循环到倒数第二个单元
​
                i <= arr.length -1 - j
                    上一次排序出的最大值 不参与下一次的循环排序
            */
            for (let i = 0; i < arr.length - 1 - j; i++) {
                if (arr[i] > arr[i + 1]) {
                    let temp = arr[i];
                    arr[i] = arr[i + 1];
                    arr[i + 1] = temp;
                }
            }
        }

        console.log('排序好的数组:',arr);

在这里插入图片描述

(三)总结

1、核心原理

  • 数组中相邻的两个单元进行数据比较
  • 如果前大后小交换两个单元存储的数据
  • 循环一次将一个最大值排序到数组末位
  • 多次循环完成,整个数组排序

2、核心优化

  • 外层:n个单元循环n-1次,完成排序
  • 内层:每次从第一个单元循环至所有需要循环单元的倒数第二个
    • 上一次排序出的最大值不参与 下一次排序

二、选择排序

在这里插入图片描述

(一)核心原理

  • 选择排序每次循环,选择最小值所在单元的索引下标
  • 如果不是本次循环起始单元的索引下标
  • 交换起始单元和最小值单元存储的数据
  • 循环一次,将一个最小值存储到数组的起始位置

(二)执行步骤

1、单独完成排序

        const arr = [9, 3, 6, 2, 4, 1, 8, 5, 7];

        console.log('原始数组: ', arr);

        // 第一轮
        // 假设当前最小数值为下标0的项
        var minIndex = 0;
        for (let i = 1; i < arr.length; i++) {
            if (arr[minIndex] > arr[i]) {
                minIndex = i;
            }
        }

        // 交换真实最小的值与下标0的值
        var temp = arr[0];
        arr[0] = arr[minIndex];
        arr[minIndex] = temp;
        console.log('第一轮选择排序结束后的数组: ', arr);


        // 第二轮
        // 假设当前最小数值为下标1的项
        var minIndex = 1;
        for (let i = 2; i < arr.length; i++) {
            if (arr[minIndex] > arr[i]) {
                minIndex = i;
            }
        }
        // 交换真实最小的值与下标1的值
        var temp = arr[1];
        arr[1] = arr[minIndex];
        arr[minIndex] = temp;
        console.log('第二轮选择排序结束后的数组: ', arr);

        // 第三轮
        var minIndex = 2;
        for (let i = 3; i < arr.length; i++) {
            if (arr[minIndex] > arr[i]) {
                minIndex = i;
            }
        }
        // 交换真实最小的值与下标2的值
        var temp = arr[2];
        arr[2] = arr[minIndex];
        arr[minIndex] = temp;
        console.log('第三轮选择排序结束后的数组: ', arr);

在这里插入图片描述

2、双重for循环,完成排序

k的值第几次循环假设谁是最小值和谁交换循环开始的值
k == 01001
k == 12112
k == 23223
    const arr = [9, 3, 6, 2, 4, 1, 8, 5, 7];

    console.log('原始数组: ', arr);

    for (let j = 0; j < arr.length; j++) {
      // 定义变量 存储最小下标
      let minIndex = j;

      for (let i = j + 1; i < arr.length; i++) {

        if (arr[minIndex] > arr[i]) {

          minIndex = i;
        }
      }
      // 交换真实最小的值与下标的值
      let temp = arr[j];
      arr[j] = arr[minIndex];
      arr[minIndex] = temp;
    }
    console.log('选择排序结束后的数组: ', arr);

在这里插入图片描述

3、代码优化

  • j <= arr.length -1
  • n个单元循环,n-1次完成整个数组排序
    const arr = [9, 3, 6, 2, 4, 1, 8, 5, 7];
    console.log('原始数组: ', arr);

    for (let j = 0; j < arr.length - 1; j++) {
      // 定义变量 存储最小下标
      let minIndex = j;

      for (let i = j + 1; i < arr.length; i++) {

        if (arr[minIndex] > arr[i]) {
          minIndex = i;
        }
      }
      // 交换真实最小下标的值
      let temp = arr[j];
      arr[j] = arr[minIndex];
      arr[minIndex] = temp;
    }
    console.log('选择排序结束后的数组: ', arr);

在这里插入图片描述

三、冒泡和选择的对比

(一)区别一

  • 冒泡排序每次循环,将一个最大值存储到数组末位
  • 选择排序每次循环,将一个最小值存储到数组起始

(二)区别二

1、冒泡排序

  • 冒泡排序相邻两个单元比较数值,如果前大后小,交换存储数据
  • 循环一次要多次执行数据交换操作

2、选择排序

  • 选择排序变量储存单元数据和循环单元数据比较数值
  • 如果变量单元数据大于循环单元数据,变量存储索引下标
  • 循环结束,判断最小值单元不是起始单元,再交换存储数据
  • 循环一次,最多执行一次数据交换操作
  • 选择排序效率更高

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/37027.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

44、Map

一、基本介绍&#xff1a; 1、Map接口实现类的特点&#xff3b;很实用&#xff3d; 注意&#xff1a;这里讲的是JDK8的Map接口特点 1&#xff09;Map与Collection并列存在。用于保存具有映射关系的数据&#xff1a;Key-Value 2&#xff09;Map 中的 key和value 可以是任何引…

5个超好用的视频素材网站,视频剪辑必备。

推荐五个高质量视频素材网站&#xff0c;免费、可商用&#xff0c;赶紧收藏起来&#xff01;1、菜鸟图库 https://www.sucai999.com/video.html?vNTYwNDUx网站素材非常丰富&#xff0c;有平面、UI、电商、办公、视频、音频等相关素材&#xff0c;视频素材质量很高&#xff0c;…

SpringBoot2.x系列教程31--SpringBoot中的缓存实现方案介绍

前言 作为一个程序员&#xff0c;我们不仅仅要把项目的功能实现出来&#xff0c;还要追求这个功能的高效和健壮&#xff0c;我们得想办法对项目的功能进行各种优化和性能的提升。其中缓存就是对程序性能进行显著提升的一个有效手段&#xff0c;那么在SpringBoot中对缓存有哪些…

我的数学学习回忆录——一个数学爱好者的反思(一)

早点关注我&#xff0c;精彩不迷路&#xff01;我是一个热爱数学20余年的数学爱好者&#xff0c;曾奉数学为宇宙的真理和一切行动的指南的极客。从小对数字世界好奇和敏感&#xff0c;玩各种数学思维游戏&#xff0c;然后在高考应试和竞赛中扎实训练数学基础&#xff0c;逐渐把…

[附源码]java毕业设计中华美食网站

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

docker安装filebeat 进行日志收集

1.介绍 filebeat和beats的关系 首先filebeat是Beats中的一员。   Beats在是一个轻量级日志采集器&#xff0c;其实Beats家族有6个成员&#xff0c;早期的ELK架构中使用Logstash收集、解析日志&#xff0c;但是Logstash对内存、cpu、io等资源消耗比较高。相比Logstash&#x…

matlab学习笔记(五)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 matlab学习笔记&#xff08;五&#xff09;一、绘制下列连续时间信号的波形图二、绘制下列离散时间信号的波形图三.已知信号f(t)的波形如下图所示&#xff0c;请用MATLAB绘出…

ES filter查询 高亮查询 聚合查询

filter查询 query&#xff0c;根据你的查询条件&#xff0c;去计算文档的匹配度得到一个分数&#xff0c;并且根据分数进行排序&#xff0c;不会做缓存的。 filter&#xff0c;根据你的查询条件去查询文档&#xff0c;不去计算分数&#xff0c;而且filter会对经常被过滤的数据进…

C++中的多态(上)

&#x1f9f8;&#x1f9f8;&#x1f9f8;各位大佬大家好&#xff0c;我是猪皮兄弟&#x1f9f8;&#x1f9f8;&#x1f9f8; 文章目录一、多态的概念二、虚函数三、破坏多态条件的现象1.破坏多态条件一&#xff0c;虚函数重写/覆盖2.破坏多态条件二四、 多态的两个条件不满足…

数据库审核工具SQLE部署及使用

点击上方蓝字关注我SQLE&#xff08; https://opensource.actionsky.com/sqle/ &#xff09;是由上海爱可生信息技术股份有限公司 开发并开源&#xff0c;支持多场景审核&#xff0c;支持标准化上线流程&#xff0c;原生支持 MySQL 审核且数据库类型可扩展的 SQL 审核工具。我们…

PC_磁盘HDD_SSD

文章目录磁盘存储器组成磁盘驱动器磁盘控制器盘片platter存储区域磁盘结构磁道track扇区sector&#x1f388;/块Block&#x1f386;磁头(Head)圆柱面cylinder磁记录原理磁盘性能指标记录密度磁盘的容量非格式化容量格式化容量数据传输率磁盘转速旋转周期T例平均存取时间纯读/写…

网络与通信程序设计-基于UDP的广播通信实例

目录 实验内容和设计思想 实验的内容 UDP的设计思想 UDP的协议头部 UDP通信编程思想 UDP的工作流程 UDP编程收发函数 广播通信 广播模式设置 广播套接字 UDP Socket的使用过程 UDP广播通信实例实现 initsock.h 服务器发送广播消息 客户端接收广播消息 运行效果 …

HttpMessageConverter 消息转换器

HttpMessageConverter 简介 HttpMessageConverter 是SpringMVC中提供的一个策略接口&#xff0c;它是一个消息转换器类&#xff0c;Spring Mvc中就是由HttpMessageConverter负责转换HTTP的请求和响应。 默认情况下&#xff0c;Spring Boot 会自动加载如下消息类型转换器&…

spring复习01,IOC的思想和第一个spring程序helloWorld

spring复习01&#xff0c;IOC的思想及本质IOC的思想一个小例子&#xff0c;来体会IOC的基础思想。dao层dao层接口dao层实现类service层service层接口service层实现类测试代码service层实现类修改测试代码修改IOC容器在spring中的简单实现创建项目在pom.xml中引入依赖实体类创建…

C# 拨号面板 高亮显示

一 拨号面板 显示&#xff1a;绘制4x3; 数据&#xff1a;每一格对应一个数字&#xff1b; 行为&#xff1a;点击单元格时有反应&#xff1b; 二 拨号事件 当点击某个号码时&#xff0c;触发拨号事件。 设计思路&#xff1a; ① 重写OnMouseClick(); ② 根据鼠标点击位置&am…

JVET-AB0117-基于模板的帧内推导的方向性融合

本提案是针对 ECM 中的 TIMD&#xff08;基于模板的帧内模式推导&#xff0c;Template based intra mode derivation &#xff09; 的技术的加权方式的改进。具体地&#xff0c;本提案提出使用方向混合&#xff08;directional blending&#xff09;来加权TIMD使用模板推导的两…

SpringBoot SpringBoot 原理篇 1 自动配置 1.13 bean 依赖属性配置

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 原理篇 文章目录SpringBootSpringBoot 原理篇1 自动配置1.13 bean 依赖属性配置1.13.1 环境准备1.13.2 bean 依赖属性配置1…

【软件测试】作为测试人,因工作与开发吵了一架碰撞,该咋办......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 测试与开发在工作中…

【网页设计】HTML+CSS保护野生动物北极熊介绍网页设计专题

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

傻白入门芯片设计,RDL/Interposer/EMIB/TSV(五)

一、再分配层&#xff08;RDL&#xff09; 主要原理就是在晶片表面沉积金属层和介电层。它形成了一个再分配层&#xff0c;以携带相应的金属布线模式&#xff0c;并在芯片外的松散区域上重新排列芯片的IO端口。由于RDL形成的金属布线的线宽和间距较小&#xff0c;从而提供了更…