【学习笔记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 );

在这里插入图片描述

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、选择排序
  • 选择排序变量储存单元数据和循环单元数据比较数值
  • 如果变量单元数据大于循环单元数据,变量存储索引下标
  • 循环结束,判断最小值单元不是起始单元,再交换存储数据
  • 循环一次,最多执行一次数据交换操作
  • 选择排序效率更高
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值