这里是一则小广告:
关注作者请点击这里哦:zdr0
我的专栏里面不仅有学习笔记,也有一些科普文章,相信我的专栏不会让您失望哦~大家可以关注一下:数学及自然科学
-尽力写最好的讲义,尽力写最好的科普。
在上一篇笔记中,我们仔细讲解了数组的选择排序。在这篇笔记中,我们在来学习另一种排序算法——冒泡排序。
我们仍拿上一篇笔记中的数组进行举例。还是一样的配方,且看这回能做出什么味道。
冒泡排序的特点是每一轮比较结束之后都会将这一轮比较中最大的元素放在最后。 这是为什么呢?我们不妨先来看第一轮比较的过程:
![c3f1a11e7edc89a7e290360a971dd22a.png](https://i-blog.csdnimg.cn/blog_migrate/024e71449cc4400f28b0916dd4adc6d7.png)
在第一轮排序中,是将相邻的两个索引的位置上的元素进行比较(实际上每一轮排序都是这样做的)。将相邻的两个元素进行比较之后,将较小的元素放在前面,而将较大的元素放在后面。
首先是索引为0的元素(即34)与索引为1的元素(即19)进行比较,发现19<34,所以应置换19和34的位置(置换完毕后19的索引为0,而34的索引为1);(至于置换的方法,在上一篇笔记中有介绍。)
然后比较的是索引为1的元素(此时为34)和索引为2的元素(即11),发现11<34,所以置换11和34的位置(置换完毕后11的索引为1,而34的索引为2);
再比较索引为2的元素(此时为34)和索引为3的元素(即109),发现109>34,所以,这一次比较结束不进行置换(此时34的索引仍为2,109的索引仍为3);
再比较索引为3的元素(此时为109)和索引为4的元素(即3),发现3<109,所以应置换3和109的位置(置换完毕后109的索引为4,而3的索引为3);
最后一次比较索引为4的元素(此时为109)和索引为5的元素(即56),发现56<109,索引应置换56和109的位置(置换完毕后109的索引为5,而56的索引为4)。
至此,第一轮比较结束。
通过这第一轮的比较我们不能发现,数组中最大的元素已经被排在了索引为5的位置上(即最后一位上)。我们不妨再来看一轮比较:
![48c9afa850ec274b2afc1c75a676f018.png](https://i-blog.csdnimg.cn/blog_migrate/637ad634b7bc88dc040cf5a1fda792f2.png)
在这新的一轮比较中,索引为5的元素已经可以不用在参与比较了,因为它已经是最大的了(这一点与选择排序是类似的,在选择排序中,第一轮比较之后我们不需要在让数组中索引为0的元素参与比较了,因为它已经是最小元素了)。
第二轮比较的过程与第一轮一致,大家可以自行分析一下。
这一轮比较之后的结果是数组中“最大”(除了109)的元素被排在了“最后一位”上(既然最后一位不参与比较,此时的最后一位的索引为4。)
通过这两轮分析我们可以发现,每一轮比较之后,“最大”的元素都被放在了“最后一位”上。这就是冒泡排序的特点。
现在我们可以来写写思想了:
- 首先,我们应该选用什么结构进行代码书写呢?我们通过分析上述过程发现,总共需要进行比较的次数为5次,分别是第一轮0到5,第二轮0到4,第三轮0到3,...,第五轮0到1,由于索引为0的元素没必要与自己比较一次,所以,没有第六轮比较。此外,第一轮比较需要5次,第二轮需要4次,...,第五轮只需要一次。所以这个过程是“大圈套小圈的过程”,所以考虑使用for 循环。
- 外循环用于控制总的比较次数(共5次),所以,外循环应为:
wxh:
- 现在是内循环。我们先来仔细分析一下内循环。内循环控制的是每一轮比较中比较的次数(或者说每一轮比较中参与比较的元素的个数)。当外循环进行第一次的时候(即进行第一轮比较的时候),内循环应该进行5次(因为第一轮比较要比较5次);当外循环进行第二次的时候(即进行第二轮比较的时候),内循环应该进行4次(因为第二轮比较要比较4次);...;当外循环进行第五次的时候(即进行第五轮比较的时候),内循环应该只进行一次(因为第五轮比较要比较1次)。所以,内循环的循环变量应该从0开始,因为每一轮比较都是从索引为0的位置开始,且每进行一轮比较,参与比较的元素个数都减少一个,所以y应该小于(arr.length-1)-x。(x=0的时候arr.length-1-0=6-1-0=5。即当x=0时,y<5,所以y从0开始到4一共可以进行5次内循环,与我们之前的分析一致。x为其他数时以此类推。arr.length-1同时也保证了数组索引不会越界,我们会在下面的完整的代码中看到。)所以,内循环为:
nxh:
- 现在式内循环中的具体方法。与选择排序一样,既然判断是否进行置换,那我们就使用if 语句就可以了。与选择排序不一样的是,这里的每次比较都是相邻元素之间的,即arr[y]与arr[y+1]进行比较。比较之后将较小的元素放在前面,将较大的元素放在后面,至于置换的方法,请参看上一篇笔记。所以,内循环中的具体方法是:
if
- 最后,我们来明确一下方法签名。首先这个函数是没有返回值的,所以使用void关键字;齐次,参与运算的参数是一个数组。所以,除了函数名以外,它的方法签名的其余部分与选择排序的方法签名是一致的,为:
public
好啦,现在我们就可以将上述四个部分的代码拼接起来称为一个完整的代码啦:
public
当然,这个代码还有其他写法,比如:
public
这个代码与之前的代码稍有不同,但原理是一致的。