冒泡排序(JS)

循环数组,比较当前元素和下一个元素,如果当前元素比下一个元素大,向上冒泡。

这样一次循环之后最后一个数就是本数组最大的数。

下一次循环继续上面的操作,不循环已经排序好的数。

优化:当一次循环没有发生冒泡,说明已经排序完成,停止循环
平均时间复杂度:O(N^2)
最佳时间复杂度:O(N)
最差时间复杂度:O(N^2)
空间复杂度:O(1)
排序方式:In-place
稳定性:稳定
/**
 * 基础冒泡排序 - 方法1
 * @param {*} arr 数组 [3, 1, 5, 4, 7, 6, 0, 2]
 * @returns sort-arr
 */
console.time('bubbleSort1');
var arr1 = [3, 1, 5, 4, 7, 6, 0, 2];
console.log('原数组', arr1);
var bubbleSort1 = arr => {
  let len = arr.length;
  if (len <= 1) return arr;
  // 外层 遍历次数 为length-1次
  for (let i = 0; i < len - 1; i++) {
    // 内层 比较次数 比较次数为length - 当前遍历次数
    for (let j = 0; j < len - 1 - i; j++) {
      if (arr[j] < arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
      }
    }
  }
  console.log('排序后数组', arr);
  return arr;
};
bubbleSort1(arr1);
console.timeEnd('bubbleSort1');

/**
 * 增加是否已排序完的标识符 isDone - 方法2
 * @param {*} arr 数组 [3, 1, 5, 4, 7, 6, 0, 2]
 * @returns sort-arr
 */
console.time('bubbleSort2');
var arr2 = [3, 1, 5, 4, 7, 6, 0, 2];
console.log('原数组', arr2);
var bubbleSort2 = arr => {
  let len = arr.length;
  if (len <= 1) return arr;
  let isDone = null;
  // 外层 遍历次数 为length-1次
  for (let i = 0; i < len - 1; i++) {
    isDone = true;
    // 内层 比较次数 比较次数为length - 当前遍历次数
    for (let j = 0; j < len - 1 - i; j++) {
      if (arr[j] > arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
        isDone = false;
      }
    }
    if (isDone) {
      console.log('排序后数组', arr);
      return arr;
    }
  }
  console.log('排序后数组', arr);
  return arr;
};
bubbleSort2(arr2);
console.timeEnd('bubbleSort2');
/**
 * 增加是否已排序完的标识符 isDone - 方法2
 * 外层for循环改为while
 * @param {*} arr 数组 [3, 1, 5, 4, 7, 6, 0, 2]
 * @returns sort-arr
 */
console.time('bubbleSort3');
var arr3 = [3, 1, 5, 4, 7, 6, 0, 2];
console.log('原数组', arr3);
var bubbleSort3 = arr => {
  let len = arr.length;
  if (len <= 1) return arr;
  let isDone = null;
  // 外层 遍历次数 为length-1次
  while (len > 1) {
    isDone = true;
    // 内层 比较次数 比较次数为length - 当前遍历次数
    for (let j = 0; j < len - 1; j++) {
      if (arr[j] > arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
        isDone = false;
      }
    }
    if (isDone) {
      console.log('排序后数组', arr);
      return arr;
    }
    len--;
  }
  console.log('排序后数组', arr);
  return arr;
};
bubbleSort3(arr3);
console.timeEnd('bubbleSort3');
/**
 * 增加是否已排序完的标识符 isDone - 方法2
 * 外层for循环改为while
 * 内层for循环改为while
 * @param {*} arr 数组 [3, 1, 5, 4, 7, 6, 0, 2]
 * @returns sort-arr
 */
console.time('bubbleSort4');
var arr4 = [3, 1, 5, 4, 7, 6, 0, 2];
console.log('原数组', arr5);
var bubbleSort4 = arr => {
  let len = arr.length;
  if (len <= 1) return arr;
  let isDone = null;
  // 外层 遍历次数 为length-1次
  while (len > 1) {
    isDone = true;
    // 内层 比较次数 比较次数为length - 当前遍历次数
    let j = 0;
    while (j < len - 1) {
      if (arr[j] > arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
        isDone = false;
      }
      j++;
    }
    if (isDone) {
      console.log('排序后数组', arr);
      return arr;
    }
    len--;
  }
  console.log('排序后数组', arr);
  return arr;
};
bubbleSort4(arr4);
console.timeEnd('bubbleSort4');
console.time('bubbleSort6');
var arr6 = [3, 1, 5, 4, 7, 6, 0, 2];
console.log('原数组', arr2);
var bubbleSort6 = arr => {
  let len = arr.length;
  if (len <= 1) return arr;
  let isDone = null;
  let lastSwapIndex = 0;
  let arrBoundary = len - 1
  // 外层 遍历次数 为length-1次
  for (let i = 0; i < len - 1; i++) {
    isDone = true;
    console.log('第'+(i+1)+'趟遍历')
    // 内层 比较次数 比较次数为length - 当前遍历次数
    for (let j = 0; j < arrBoundary; j++) {
      if (arr[j] > arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
        isDone = false;
        lastSwapIndex = j
      }
      console.log('第'+(j+1)+'次比较,当前比较移动后的数组'+arr)
    }
    arrBoundary = lastSwapIndex
    if (isDone) {
      console.log('排序后数组', arr);
      return arr;
    }
  }
  console.log('排序后数组', arr);
  return arr;
};
bubbleSort6(arr6);
console.timeEnd('bubbleSort6');

参考链接:
冒泡排序参考1
冒泡排序参考2
冒泡排序参考3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值