21. 详细解剖 冒泡排序

56 阅读4分钟
import { ref } from "vue";

const data = ref({});
const getdata = ()=>{
    for(let a = 1;a<=12 ;a++){

       data.value[parseInt(Math.random()*11+1) +'月'] = parseInt(Math.random()*1000+50) 
    }
}
  • 排序的数据
const data1 = ref({ "5月": 375, "2月": 1032, "6月": 732, "4月": 374, "1月": 561, "3月": 474, "7月": 81 })
  • 取出月中的number(数字),也就是和月分开 使每一项数据可比

  • 再将大的数据放到后面,这样就实现了递增

  • 要实现这一步 首先要取出来对象的 key值

  • 可以使用 Object.keys() 取出每一项的 key 值

let arr1 = Object.keys(data1.value)
console.log(arr1,'数组1');

image.png

  • 取出月份数字
let arr2 = arr1.map((item,index)=>{
    return item.slice(0,item.indexOf('月'))
})
console.log(arr2,'数组2');

image.png

冒泡排序

  • 对他们进行排序,这里选择冒泡排序法
let leng = arr2.length
  • for(var a= 0;a<leng;a++){} 这里声明了一个a 并设置了循环的结束条件

  • 也就是a小于arr2的长度,只有符合条件才会执行,不符合则循环结束

  • 如果 数组的长度是 6 那当 6小于6不成立时, 结束循环 0-5 共执行了 6 次

  • 接下来是对数据位置进行置换 两两比较 较大的放后面

  • 如:

    • let arr = [5,2,6,4,1,3,7,]: 月份
    • 循环时分别取出当前值 和后一位数值
   for(var i= 0;i<leng;i++){
           arr[i]// 循环中的当前值
           arr[i+1]// 循环的后一位值
       };
  • 将它每一步执行拆出来看会更容易理解

image.png

  • 最终得到的结果是 [2,5,4,1,3,6,7];
  • 原来的数组数据---[5,2,6,4,1,3,7];
  • 可以看到 里面的最大值被放在了最后一位
  • 完成了一部分的排序,之后就是将对比再执行一遍,但是不能让上次最大值参与
  • 思考一下怎么才能不带着上面的 7 参加下一次的循环对比
  • ...

image.png

  • 想让他不对比到上一次的数据 可以少对比一次 , 按照循环条件来说 只要条件稍微变化就能够减少对比次数

  • 比如 i的对比值 递减 就能使对比次数减一

  • 先不慌怎么个递减法 排除这条件,假设能满足条件 对比次数 递减

  • 那 要将每次循环的最大值 放到后面,需要几次呢 ,注意:是放到的动作次数

  • 带入一下 第一次是 7 第二次是 6 第三次是 5 ...4 ...3 ...2 ...1?

  • ...1?已经不需要了,将2放到后面之后就已经决定了 最后一个值的顺序

  • 也就是 6次

  • 循环 6次的可以写为 for(var a= 0;a<leng;a++){}; leng = 6; a 的值在 0-5 之间都是满足条件的 也就是6次


  • 这个循环是决定了提取最大值的次数

  • 要想将 两个数值的顺序对调那肯定是需要将一个值另存一下,不然两个位置直接对调 总会少一个值

  • 如 将大值赋给索引加一 那索引加一的位置的值就会丢失

  • 因此执行步骤为

  for(var a= 0; a<leng; a++){
            // 少对比一次 肯定是for 循环里的条件递减 而 上次循环的 a 是每次递增的
            // 于是
            for(var i= 0; i<leng -i; i++){// i < 7; 0-6 循环六次
                if(arr[i] > arr[i+1]){
                    let tamp = 0;
                    tamp = arr[i+1];  // 这样后面的位置的值就被存了起来
                    arr[i+1] = arr[i];// 将大值放到后面的位置 便于进行下一次对比
                    arr[1] = tamp;    // 将对比中较小的值放到arr[1] 的位置                    
                }
            };
        };
  • 如果没看懂 请看示例 可以带入--[5,2,6,4,1,3,7]
        let tamp = 0;
        tamp     = arr[i+1]/ arr[1] / 2;    tamp = 2;
        arr[i+1] = arr[i]  / arr[0] / 5;    arr[i+1]/ arr[1] = 5;
        arr[i]   = tamp    / 2;             arr[i]/ arr[0] = 2;
    
        // 第一次的结果 [2,5,6,4,1,3,7]
        // 也就是 i 的循环
  • 外层的 a 第二次 循环
  for(var a= 0; a<leng; a++){
            // 少对比一次 肯定是for 循环里的条件递减 而 上次循环的 a 是每次递增的
            for(var i= 0; i<leng -i; i++){// i < 6; 0-5 循环五次
                if(arr[i] > arr[i+1]){
                    let tamp = 0;
                    tamp = arr[i+1];
                    arr[i+1] = arr[i];
                    arr[1] = tamp;                   
                }
            };
        };
        // 结果为 [2,5,4,1,3,6,7] 
        // 2和5 一次 1
        // 5和6 一次 2
        // 6和4 一次 3
        // 6和1 一次 4
        // 6和3 一次 5

偶吼吼,就是如此,理解了吗.