冒泡排序算法

news/2024/7/7 7:16:42

如下是一个基本的冒泡排序算法,执行的过程

  • 外部循环len次

  • 内部循环每次用arr[i]的值与arr[j]的值进行比较

  • 由于外部循环的i变量每次进入内部循环都不会改变,也就是arr[i]的值进入内部循环后,都会以自身与arr[j](也就是整个数组的所有元素)比较一轮,结果是小于arr[i]的数值都会被放到数组的开头

  • 经过外层循环的一次次的进入内层循环的比对后,数组也依照从小到大的顺序排列了

let arr = [1, 3, 2]
let len = arr.length

for(let i = 0; i < len; i++){
    for(let j = 0; j < len; j++){
        if(arr[i] > arr[j]){
            let temp = arr[i]
            arr[i] = arr[j]
            arr[j] = temp
        }
    }
}

我们来分解步骤

第一轮外层循环 i = 0
    第一轮内部循环 
    j = 0
    
    arr[i] = 1 arr[j] = 1 arr[i] > arr[i]不成立,j++, arr保持现状 [1, 3, 2]
    
    j = 1
    
    arr[i] = 1 arr[j] = 3 arr[i] > arr[j]不成立,j++, arr保持原样 [1, 3, 2]
    
    j = 2
    
    arr[i] = 1 arr[j] = 2 arr[i] > arr[j]不成立,j++, arr保持原样 [1, 3, 2]
    
    j = 3
    
    arr[i] = 1 arr[j] = undefined 由于len = 3 ,故 j < len不成立,第一轮层循环结束
第二轮外层循环 i = 1
    第二轮内部循环
    j = 0
    
    arr[i] = 3 arr[j] = 1 arr[i] > arr[i]成立, arr[i]和arr[j]交换数值,arr更新为[3, 1, 2]
    
    j = 1
    
    arr[i] = 1 arr[j] = 1 arr[i] > arr[i]不成立,j++, arr保持原样 [3, 1, 2]
    
    j = 2
    
    arr[i] = 1 arr[j] = 2 arr[i] > arr[i]不成立,j++, arr保持原样 [3, 1, 2]
    
    j = 3
    
    arr[i] = 1 arr[j] = undefined 由于len = 3 ,故 j < len不成立,第二轮层循环结束
第三轮外层循环 i = 2
    第三轮内部循环
    j = 0
    
    arr[i] = 2 arr[j] = 3 arr[i] > arr[i]不成立,j++, arr保持原样 [3, 1, 2]
    
    j = 1
    
    arr[i] = 2 arr[j] = 1 arr[i] > arr[i]成立, arr[i]和arr[j]交换数值,arr更新为[3, 2, 1]
    
    j = 2
    
    arr[i] = 1 arr[j] = 1 arr[i] > arr[i]不成立,j++, arr保持原样 [3, 2, 1
    
    j = 3
    
    由于众所周知的原因,第三轮内部循环结束

第四轮外层循环 i = 3

由于i < len不成立,外部循环结束,现在我们的数组最终结果为[3, 2, 1]

接下来我们来看看有没有优化的空间

我们发现,每次内部循环都市从索引 let j = 0; 开始的,也就是说每次内部循环 arr[j]
都会把数组遍历一遍,由于在上一次的内部循环结束后,都会把最大的数放到数组的头部,所以再次进入内部循环时,如果还去从头比较就是浪费时间

所以如何让内部循环将上次列入最大值的位置忽略呢?

答案就是i变量,每次结束一次外部循环i变量都会加1,这也代表着有i个最大值被置于数组头部,也就是我们需要忽略的位置,所以,我们只需要将内部循环的起始位置i加上i,就可以将已经确定的位置忽略比较

for(let i = 0; i < len; i++){
    for(let j = 0 + i; j < len; i++){
        // 直接简写成let j = i也行
    }
}


然后我们来验证一下优化的成果

用一个大一点的数组,并且记录下循环次数

let arr = [0,1,2,44,4,324,5,65,6,6,34,4,5,6,2,43,5,6,62,43,5,1,4,51,56,76,7,7,2,1,45,4,6,7]
let len = arr.length
let count = 0

for(let i = 0; i < len; i++){
  for(let j = 0; j < len; j++){
    count++
    if(arr[i] > arr[j]){
      let temp = arr[i]
      arr[i] = arr[j]
      arr[j] = temp
    }
  }
}

console.log(arr, count)
arr = [324, 76, 65, 62, 56, 51, 45, 44, 43, 43, 34, 7, 7, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 2, 2, 2, 1, 1, 1, 0]
count = 1156次

下面看下优化过的

let arr = [0,1,2,44,4,324,5,65,6,6,34,4,5,6,2,43,5,6,62,43,5,1,4,51,56,76,7,7,2,1,45,4,6,7]
let len = arr.length
let count = 0

for(let i = 0; i < len; i++){
  for(let j = i; j < len; j++){
    count++
    if(arr[i] > arr[j]){
      let temp = arr[i]
      arr[i] = arr[j]
      arr[j] = temp
    }
  }
}

console.log(arr, count)
arr = [0, 1, 1, 1, 2, 2, 2, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 34, 43, 43, 44, 45, 51, 56, 62, 65, 76, 324]
595次

结果毋庸置疑减少了近半数的无用循环,那么到此为止了吗?
让我们再来看看
我们现在用的比较方式是基于用数组中的一个位置与所有位置进行比较,然后在下一轮比较时忽略已经确定的位置,
如下:
[1, 3, 2]

1 比 1

1 比 3

1 比 2

大家是不是发现了一个无效操作?就是1和1比较,这就是一个无效操作,由于外部循环的i和内部循环的j初始化会相等,所以arr[i]和arr[j]会取到同一个位置的值比较一次,那么怎么优化这个操作呢?

答案就是让内部j从第二位开始,避免和arr[i]取同一个值的情况

for(let i = 0; i < len; i++){
    for(let j = i; j < len - 1; j++){
       if(arr[i] > arr[j+1]){
           temp = arr[i];
           arr[i] = arr[j+1];
           arr[j+1] = temp;
       } 
    }
}

注意我给内部循环的len减去了1,是由于给j+1的会导致最后一次arr[j+1]会溢出数组,所以将其减1,正好弥补了j+1,也不会出现少遍历数组元素的情况

然后我们来看看成果

[0, 1, 1, 1, 2, 2, 2, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 34, 43, 43, 44, 45, 51, 56, 62, 65, 76, 324]
561次

http://www.niftyadmin.cn/n/2134912.html

相关文章

华存数据可视化_大数据技术的应用现状与展望.pdf

大数据技术的应用现状与展望视点聚焦大数据技术的应用现状与展望廖建新(北京邮电大学网络与交换技术国家重点实验室 北京 100876)摘 要 &#xff1a;梳理 了大数据研究的4项关键技术 &#xff1a;“数据的采集、预处理与存储 ”、“数据 的分析与挖掘 ”、“数据 的隐私保护 ”…

python编程怎么画三角形的外接圆_python画出三角形外接圆和内切圆的方法

刚看了《最强大脑》中英对决&#xff0c;其中难度最大的项目需要选手先脑补泰森多边形&#xff0c;再找出完全相同的两个泰森多边形。在惊呆且感叹自身头脑愚笨的同时&#xff0c;不免手痒想要借助电脑弄个图出来看看&#xff0c;闲来无事吹吹牛也是极好的。今天先来画画外接圆…

Ruby中使用patch HTTP方法

Ruby中使用patch HTTP方法 如果使用patch&#xff0c;在后台可以看到只更新了改动的部分&#xff1b; Started PATCH "/ads/5/update" for ::1 at 2017-04-20 20:12:40 0800 Processing by AdsController#update as HTMLParameters: {"utf8">"✓&q…

JAVA必会算法--冒泡排序

pop(int[] a){ for(int i 0;i<a.length;i){ for(int ja.lenght-1;j>0;j){ if(a[j]>a[j1]){ int tmp a[j]; a[j] a[j1]; a[j1] tmp; } } } }转载于:https://www.cnblogs.com/fastLearn/p/6742862.html

求任意个连续整数的和 python_Python:list是否包含3个连续的整数,总和为7?

我正在为我的编码训练营准备应用程序的准备材料.这是我在使用(使用Python)时遇到的实践问题&#xff1a;“编写一个函数’lucky_sevens(numbers)’,该函数接收一个整数列表,如果任意三个连续元素的总和为7,则输出True.确保您的代码正确检查数组的第一个和最后一个元素.”我知道…

手把手教你用Strace诊断问题[转]

早些年&#xff0c;如果你知道有个 strace 命令&#xff0c;就很牛了&#xff0c;而现在大家基本都知道 strace 了&#xff0c;如果你遇到性能问题求助别人&#xff0c;十有八九会建议你用 strace 挂上去看看&#xff0c;不过当你挂上去了&#xff0c;看着满屏翻滚的字符&#…

后台启动_Nohup后台启动不输出及文件过大的问题

1. 背景在Linux中常常使用nohup的方式启动程序&#xff0c;目的是当关闭终端时程序能自由的后台执行&#xff0c;nohup启动会将程序输出信息进行保持到nohup.out文件中&#xff0c;久而久之此文件会过于庞大&#xff0c;且程序有自己的日志系统&#xff0c;所以nohup的纪录往往…

element ui表格打印_element-ui 表格打印

打印需要用到的组件为 print-js普通表格打印一般的表格打印直接仿照组件提供的例子就可以了。printJS({printable: id, // DOM idtype: html,scanStyles: false,})element-ui 表格打印element-ui 的表格&#xff0c;表面上看起来是一个表格&#xff0c;实际上是由两个表格组成的…