冒泡排序及变形 Bubble Sort

2020-11-19  本文已影响0人  HROKKO

一、基本思想

二、算法实质

三、基础算法

for (let i = 0; i < arr.length - 1; i++) {
  for (let j = 0; j < arr.length - 1 - i; j++) {
    if (arr[j] > arr[j + 1]) { // 相邻的比较大小,大的放右边
      let temp = arr[j]; // [arr[j], arr[j + 1]] = [arr[j+1], arr[j]]
      arr[j] = arr[j + 1];
      arr[j + 1] = temp;
    }
  }
}

四、复杂度

五、算法改进

1、外层减少循环次数
let flag = true; // 表示在一次循环中是否发生了数据交换
for (let i = 0; i < arr.length - 1; i++) {
  // flag为false时,上一次循环已经没有发生数据交换,证明顺序已经排完了
  if (!flag) {
    break;
  }
  flag = false; // 每次循环都先置为false,即认为不会发生交换
  for (let j = 0; j < arr.length - 1 - i; j++) {
    if (arr[j] > arr[j + 1]) {
      flag = true; // 发生数据交换,则要继续比较
      let temp = arr[j];
      arr[j] = arr[j + 1];
      arr[j + 1] = temp;
    }
  }
}
2、内层减少循环次数
let k = arr.length -1; // 动态k,记录上一次内循环的上界值,因为k以后的数没有再发生数据交换,证明k以后的数顺序正确,则下一次的内循环只需比较截止到位置k的数
for (let i = 0; i < arr.length - 1; i++) {
  let lastFlag = 0; // 用于记录内循环交换数据的位置,每次循环初始化为0
  for (let j = 0; j < k - i; j++) {
    if (arr[j] > arr[j + 1]) {
      lastFlag = j; // 记录最后一次交换数据的位置
      let temp = arr[j];
      arr[j] = arr[j + 1];
      arr[j + 1] = temp;
    }
  }
  if (lastFlag === 0) { // 内循环不再交换,则排序结束,外循环也可break掉
    break;
  }
  k = lastFlag; // 让下一次循环的上界值变成此次循环的最后一次交换的位置
}

六、算法变形

1、优先选出小的放右边
for (let i = 0; i < arr.length - 1; i++) {
  for (let j = 0; j < arr.length - 1 - i; j++) {
    if (arr[j] < arr[j + 1]) { // 相邻的比较大小,小的放右边
      let temp = arr[j];
      arr[j] = arr[j + 1];
      arr[j + 1] = temp;
    }
  }
}
2、由大到小排列,但无法引入内循环标志位
for (let i = 0; i < arr.length - 1; i++) {
  for (let j = i + 1; j < arr.length; j++) {
    if (arr[i] < arr[j]) { // 优先选出大的放左边
      let temp = arr[i];
      arr[i] = arr[j];
      arr[j] = temp;
    }
  }
}
上一篇 下一篇

猜你喜欢

热点阅读