前端也要会的冒泡排序

1,887 阅读2分钟

【漫画:什么是冒泡排序?】https://juejin.cn/post/6844903688415215624

常规

let arr = [5, 8, 6, 3, 9, 2, 1, 7];
//外层循环,控制轮数,每一次找到一个最大值,把最大值置换到数组最后
let len = arr.length - 1 //需要减去1,因为后面会有j+1。
for (let i = 0; i < len; i++) {
    for (let j = 0; j < len - i; j++) {  //这里要减去一个i,因为进行到第i轮时,数组最后i个数已经排好序了。
        if (arr[j] > arr[j + 1]) { //需要把大叔置换到数组后面
            [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; //es6解构方式转换数组位置,不需要定义额外变量。
        }
    }
}
console.log(arr); // [1, 2, 3, 5, 6, 7, 8, 9]

优化

这一版代码做了小小的改动,利用布尔变量flag作为标记。如果在本轮排序中,元素有交换,则说明数列无序;如果没有元素交换,说明数列已然有序,直接跳出大循环

冒泡排序总会执行(N-1)+(N-2)+(N-3)+..+2+1趟,但如果运行到当中某一趟时排序已经完成,或者输入的是一个有序数组,那么后边的比较就都是多余的,为了避免这种情况,我们增加一个flag,判断排序是否在中途就已经完成(也就是判断有无发生元素交换)

function bubbleSort (arr) {
  let len = arr.length - 1
  for (let i = 0; i < len; i++) {
    let flag = true;
    for (let j = 0; j < len - i; j++) {
      if (arr[j] > arr[j + 1]) {
        flag = false; //元素有交换,则说明数列无序;
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
      }
    }
    if (flag) break;
  }
  return arr;
}

变种

对于冒泡排序来说,能不能传入第二个参数(参数为函数),来控制升序和降序?

function buddle_sort(arr,fn){
    let len = arr.length - 1
    for (let i = 0; i < len; i++) {
        for (let j = 0; j < len - i; j++) {
            if (fn(arr[j], arr[j + 1]) > 0) {  //arr[j] - arr[j + 1]>0 大于0升序,小于0降序
                [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
            }
        }
    }
}
let arr=[5, 8, 6, 3, 9, 2, 1, 7]
​
buddle_sort(arr, (a, b) => a - b)
console.log(arr)//[1, 2, 3, 5, 6, 7, 8, 9]buddle_sort(arr, (a, b) => b - a)
console.log(arr)// [9, 8, 7, 6, 5, 3, 2, 1]

这样也行

function buddle_sort(arr,fn){
    let len = arr.length - 1
    for (let i = 0; i < len; i++) {
        for (let j = 0; j < len - i; j++) {
            if (fn(arr[j], arr[j + 1])) {  //这样也行 ,把判断挪出去
                [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
            }
        }
    }
}
let arr=[5, 8, 6, 3, 9, 2, 1, 7]
​
buddle_sort(arr, (a, b) => a - b>0) //这里直接判断是否大于0 不用将ab反过来计算
console.log(arr)//[1, 2, 3, 5, 6, 7, 8, 9]buddle_sort(arr, (a, b) => a - b<0) //这里直接判断是否大于0 不用将ab反过来计算
console.log(arr)// [9, 8, 7, 6, 5, 3, 2, 1]