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


    笔记首发

    一、冒泡排序

    在这里插入图片描述

    (一)核心原理

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

    (二)执行步骤

    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 );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    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 );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在这里插入图片描述

    3、代码程序的优化

    外层优化

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

    内层优化

    1. 当前单元和下一个单元进行数据比较,最后一个单元没有下一个单元进行数据比较
      内层循环是从数组的第一个单元循环至循环的倒数第二个单元
    2. 上一次排序排序出最大值, 不参与 下一次的循环排序
      第一次是 1-9 单元排序 少排序0个单元
      第二次是 1-8 单元排序 少排序1个单元
      第三次是 1-7 单元排序 少排序2个单元
      第四次是 1-6 单元排序 少排序3个单元
      .....
      少排序的单元个数 0 1 2 3 4... 
      正好对应外层循环变量的数值
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
            // 定义一个数组 
            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
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这里插入图片描述

    (三)总结

    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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    在这里插入图片描述

    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);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在这里插入图片描述

    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
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    三、冒泡和选择的对比

    (一)区别一

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

    (二)区别二

    1、冒泡排序
    • 冒泡排序相邻两个单元比较数值,如果前大后小,交换存储数据
    • 循环一次要多次执行数据交换操作
    2、选择排序
    • 选择排序变量储存单元数据和循环单元数据比较数值
    • 如果变量单元数据大于循环单元数据,变量存储索引下标
    • 循环结束,判断最小值单元不是起始单元,再交换存储数据
    • 循环一次,最多执行一次数据交换操作
    • 选择排序效率更高
  • 相关阅读:
    【408篇】C语言笔记-第九章(数据结构概述)
    同花顺自动化交易股票下单接口API量化系统,别信那些外挂插件和软件,头部券商有现成的接口
    【吴恩达机器学习笔记】
    TopoLVM: 基于LVM的Kubernetes本地持久化方案,容量感知,动态创建PV,轻松使用本地磁盘
    第二课 Python的语言环境
    黑马点评-发布探店笔记
    【Python进阶-PyQt5】00搭建PyQt5环境
    Python+超市进销存 毕业设计-附源码211549
    行列式【线性代数系列(一)】
    P1600 [NOIP2016 提高组] 天天爱跑步
  • 原文地址:https://blog.csdn.net/m0_58190023/article/details/128047684