冒泡排序:

冒泡排序

逻辑

  1. 遍历数组,两两对比,把相对较大的数字向后移动
  2. 遍历一遍以后,得到的结果就是最大数字一定在后面
  3. 重复步骤1,继续比较,两轮以后,最大的两个数字一定排在最后两个位置
  4. 不管多少数字,只要比较总长度 -1 轮,那么数组排序就完成了

步骤分析

步骤0:

交换数组内两个位置的数据

借助第三个变量来实现,交换 [0] 和 [1] 位置的数据

var tmp = arr[0]
arr[0] = arr[1]
arr[1] = tmp
tmp = null
conso console.log('交换完毕 : ', arr)

步骤1

遍历数组, 两两比较进行对调

  • 假设: 数组的 length === 9
  1. 随着遍历, 最后一次一定拿到的
  2. => 当前是 arr[8]
  3. => 下一个是 arr[9]
  • 因为 length 是 9, 一定不会有 arr[9] 的数据
  1. => 我们的最后一次比较是没有意义的
  2. => 在遍历数组的时候, 少遍历一次就可以了
  • 假设数组 length === 9
  1. => 值遍历到 8
  2. => 最后一次的当前: arr[7]
  3. => 最后一次的下一个: arr[8]
 for (var i = 0; i < arr.length - 1; i++) {
      // 在循环内, i 充当每一个的索引
      // 在循环内, arr[i] 就表示当前的每一个数据
      // 在循环内, arr[i + 1] 就表示下一个数据
      // console.log(arr[i], arr[i + 1])
      // 比较进行移动
      // console.log('过程 : ', arr[i], ' > ', arr[i + 1], arr[i] > arr[i + 1])
      if (arr[i] > arr[i + 1]) {
        // 这里的代码执行, 表示当前这个比下一个大
        // arr[i] 和 arr[i + 1] 进行数据交换
        var tmp = arr[i]
        arr[i] = arr[i  + 1]
        arr[i + 1] = tmp
        tmp = null
      }
    }
    console.log('一遍以后 : ', arr)

步骤2

  1. 重复执行步骤1, 重复 length - 1 次
  2. 遍历数组, 遍历 length - 1 次
  3. 在整体比较的过程中, 每一轮减少一次
    • 当 j === 0 的时候, 第 1 轮, 完整比较 8 次 8 - 0
    • 当 j === 1 的时候, 第 2 轮, 完整比较 7 次 8 - 1
    • 当 j === 2 的时候, 第 3 轮, 完整比较 6 次 8 - 2
    • 当 j === 7 的时候, 第 8 轮, 完整比较 1 次 8 - 7
for (var j = 0; j < arr.length - 1; j++) {
      for (var i = 0; i < arr.length - 1 - j; i++) {
        console.log('过程 : ', arr[i], ' > ', arr[i + 1], arr[i] > arr[i + 1])
        if (arr[i] > arr[i + 1]) {
          var tmp = arr[i]
          arr[i] = arr[i  + 1]
          arr[i + 1] = tmp
          tmp = null
        }
      }
      console.log('一遍以后 : ', arr)

    }
    console.log('排序以后以后 : ', arr)

注意:

一旦有一轮出现全部 false 的情况, 从这一轮以后, 就再也不需要比较了,我们只要判断出本轮是不是全 false 就可以了

问题: 如何判断出本轮全是 false
  • 就看 if 内的代码是否有执行过

  • 因为只有 true 的时候才会执行 if 内的代码

  • 如果这一轮之内, if 内的代码从来没有执行过, 那么就是全 false

  • 在此之后的所有内容都不需要了

  • 代码:

每一轮开始之 前, 假设一个变量, 值为 false

我认为本轮全都是 false, 只要 if 内的代码执行了, 推翻我的假设

 for (var j = 0; j < arr.length - 1; j++) {

      // 每一轮的开始之前, 假设一个变量
      var flag = false

      for (var i = 0; i <script arr.length - 1 - j; i++) {
        console.log('过程 : ', arr[i], ' > ', arr[i + 1], arr[i] > arr[i + 1])
        if (arr[i] > arr[i + 1]) {
          var tmp = arr[i]
          arr[i] = arr[i  + 1]
          arr[i + 1] = tmp
          tmp = null

          // 这里的代码只要执行了, 那么就表示有 true 的, 本轮我的假设不对了
          flag = true // 推翻我的假设
        }
      }

      // 一轮完毕以后, 只要 flag 还是 false, 说明本轮没有任何改变
      // 从这一轮以后的内容就不需要了
      if (!flag) break

      console.log('一遍以后 : ', arr)
    }

    console.log('最终以后 : ', arr)


// 冒泡排序
    // 外层循环决定比较多少轮
    for (var i = 0; i < arr.length - 1; i++) {

      // 1. 做假设
      var flag = false

      // 2. 遍历比较
      for (var j = 0; j < arr.length - 1 - i; j++) {
        if (arr[j] > arr[j + 1]) {
          var tmp = arr[j]
          arr[j] = arr[j + 1]
          arr[j + 1] = tmp
          tmp = null

          // 推翻假设
          flag = true
        }
      }

      // 3. 根据假设变量决定是否有后续内容
      if (!flag) break
    }

    console.log('排序之后 : ', arr)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值