💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
>[warning]冒泡排序(最经典的算法) ---- > 相邻比较, 多跑几次 ---- 看图说话 ![](https://box.kancloud.cn/5a15e1d04745123a0cc6de5a90e881d9_580x580.gif) 这里使用JavaScript代码实现: 1. 先学会交换2个变量的值 ~~~ let a = 10, b = 20; let c = a; a = b; b = c; console.log(a, b); ~~~ 2. 遍历数组, 交换相邻2个位置元素的值 ~~~ let arr = [2, 5, 8, 1, 3, 4, 10, 9]; for (let i = 0; i < arr.length - 1; i++){ let c = arr[i + 1]; arr[i + 1] = arr[i]; arr[i] = c; } console.log(arr); // 注意遍历时长度要-1, 当i到7时i+1超出数组下标了, 会动态导致arr.length变大, 导致死循环 ~~~ 3. 遍历一个数组, 当i位置元素大于i+1位置元素, 再交换相邻2个元素位置 ~~~ let arr = [2, 5, 8, 1, 3, 4, 10, 9]; for (let i = 0; i < arr.length - 1; i++){ if (arr[i] > arr[i + 1]){ let c = arr[i + 1]; arr[i + 1] = arr[i]; arr[i] = c; } } console.log(arr); ~~~ 4. 我们只需要让上面的for循环的代码多执行几次, 就可以排好整个数组呢? ~~~ let arr = [2, 5, 8, 1, 3, 4, 10, 9]; for (let h = 0; h < arr.length; h++) { for (let i = 0; i < arr.length - 1; i++) { if (arr[i] > arr[i + 1]) { let c = arr[i + 1]; arr[i + 1] = arr[i]; arr[i] = c; } } } console.log(arr); ~~~ ----------- ## 扩展1: ~~~ // 外层循环可以优化 // 最坏情况, 当h的值为7时, 其实这个时候数组已经排好序了, 没有必要再执行了, 所以最外层-1 ~~~ 优化后代码 ~~~ let arr = [2, 5, 8, 1, 3, 4, 10, 9]; for (let h = 0; h < arr.length - 1; h++) { for (let i = 0; i < arr.length - 1; i++) { if (arr[i] > arr[i + 1]) { let c = arr[i + 1]; arr[i + 1] = arr[i]; arr[i] = c; } } } console.log(arr); ~~~ ----- ## 扩展2: ~~~ // 内层循环可以优化 /* * h的值, 数组结果 * 0 [2, 5, 1, 3, 4, 8, 9, 10] * 1 [2, 1, 3, 4, 5, 8, 9, 10] * h为1时, 下角标为7的元素, 不必再参加下次比较了, 因为它已经是最大了, 所以内层循环不光-1 还要 -h */ ~~~ 优化后代码: ~~~ let arr = [2, 5, 8, 1, 3, 4, 10, 9]; for (let h = 0; h < arr.length - 1; h++) { for (let i = 0; i < arr.length - 1 - h; i++) { if (arr[i] > arr[i + 1]) { let c = arr[i + 1]; arr[i + 1] = arr[i]; arr[i] = c; } } } console.log(arr); ~~~ ----- ## 扩展3: ~~~ // 上面的代码可以优化, 思考, 每次for循环后数组最新的情况得知 /* * h的值; 数组结果 * 0 [2, 5, 1, 3, 4, 8, 9, 10] * 1 [2, 1, 3, 4, 5, 8, 9, 10] * 2 [1, 2, 3, 4, 5, 8, 9, 10] * */ // 我们发现执行3次就排好序了, 但是代码会继续执行完毕, 直到h大于8才停止. 所以 // 如果内层if, 没发生过交换, 就让最外层循环停下来吧 ~~~ 优化后代码: ~~~ let arr = [2, 5, 8, 1, 3, 4, 10, 9]; let flag = true; // 标记发生没发生过交换 for (let h = 0; h < arr.length - 1 && flag; h++) { flag = false; for (let i = 0; i < arr.length - 1 - h; i++) { if (arr[i] > arr[i + 1]) { let c = arr[i + 1]; arr[i + 1] = arr[i]; arr[i] = c; flag = true; // 发生交换了, 因为if里执行了 } } } ~~~