简介
冒泡排序(Bubble Sort)是一种最简单的排序算法,它的实现方法是元素重复访问要排序的值,并且访问过程 中依次比较两个元素,如果顺序(例如从小到大,A-Z)根据算法的不同而出现错误就把它们的位置进行交换,直到元素没有再需要交换的值为止,或者说元素列表已经按从大到小或从小到大排列完成为止,越大的元素会经过算法的交换和比对慢慢浮到元素列的顶端,故名为“冒泡”。
算法描述
- 比较相邻的两个元素,如果第一个元素比第二个大,就交换两个元素的位置,例如21,经过排序比较之后就会变成12。
- 对元素本身和相邻的元素进行比较,直到结尾为止,最后的元素肯定是最大的数。
- 当第一个元素和其它比对完成后,继续从开头元素进行下一轮比较。
冒泡排序实现(Java)
首先贴出Java代码实现冒泡算法的代码。
public class Bubble {public static void main(String[] args) {int[] arrays = { 6,5,4,3,2,1 };System.out.println("排序之前:==> " + Arrays.toString(arrays));int temp = 0; // 存放临时数据// 核心代码for (int i = 0; i < arrays.length - 1; i++) {for (int j = 0; j < arrays.length -i -1; j++) {if (arrays[j] > arrays[j + 1]) {temp = arrays[j];arrays[j] = arrays[j + 1];arrays[j + 1] = temp;}}}System.out.println("排序之后:==>" + Arrays.toString(arrays)); // 调用toString方法打印数组}}
- 打印结果

从图中可以看到分别打印出了排序前的数值,和排序完之后的数值,由一开始的逆序变为排序后的正序。从而达到正序排序的效果。
冒泡算法分析
首先需要创建一个int类型的数组,并且添加五个数。代表进行排序的元素值
int[] arrays = { 6,5,4,3,2,1 };
然后定义一个 `count` 变量,作用于存储临时变量,并进行数值的互换。
int count = 0; // 存放临时变量
实现动态排序的效果要先定义一个外层for循环,对arrays数组进行所有值的遍历,这里需要用到.length方法
for (int i = 0; i < arrays.length - 1; i++) {}
首先在for循环中定义了一个变量i,并且初始值从0开始,i 小于数组的总长度减1,这里的-1指的是最多做n-1次排序。而这一层for循环的意义是指定排序的次数,也就是根据数组中定义的数值个数得出,并且通过.length方法实现。
内部嵌套循环:第二层for循环是进入排序后比较的次数,如果当前比较元素没有可比值则跳出此次内循环
for (int j = 0; j < arrays.length -i -1; j++) {}
同样在循环里定义一个变量 j ,初始值为0开始,并且小于数组的长度,减 i 减 1 ,减 i 操作是防止排序完毕后没有可排序元素时,重复循环一遍的操作,相反减 1 操作是因为初始值是从0开始,避免索引越界。
接下来就是核心判断的操作,通过内循环的比对进行位置的交换。
// 通过前一位元素和后一位元素进行比较,如果前一位元素比后一位元素值大,就交换两个值的位置。if (arrays[j] > arrays[j + 1]) {count = arrays[j]; // 赋值给count变量arrays[j] = arrays[j + 1]; // 将后+1的后一位元素赋值给前一位元素,arrays[j + 1] = count; // 将count变量赋值给后一位元素}
如果前一位元素大于后一位元素才会继续往下走,首先if语句通过拿到内循环
arrays[j]的值去判断是否 >arrays[j + 1],也就是是否大于后一位元素,如果大于则进行值的交换,也就是 把arrays[j]的值交给count来存放,紧接着将arrays[j+1]的值(后一位元素)和arrays[j]的值(前一位元素) 进行交换,最后再将count变量的值赋给arrays[j+1],此时就完成了第一轮的两个元素之间的排序。
- 按照上面的步骤就是如下所示:
- 第一轮排序:
- 排序前:6 5 4 3 2 1
- 第一次排序:5 6 4 3 2 1 6比5大,交换两个数的位置
- 第二次排序:5 4 6 3 2 1 接着和4比较,6比4大,交换其位置
- 第三次排序:5 4 3 6 2 1 和3比较,6比3大,交换其位置
- 第四次排序:5 4 3 2 6 1 和2比较,6比2大,交换其位置。
- 第五次排序:5 4 3 2 1 6 最后再和1比较,6比1大,此时最大的元素6已经到了最顶层,第一轮排序结束。
- 至此内循环第一轮结束,最大元素6升至最顶层,也就是5,4,3,2,1,6的顺序,紧接着跳至外层循环继续下一轮从5开始排序。
- 第二轮排序:
- 排序前:5 4 3 2 1 6
- 第一次排序:4 5 3 2 1 6 5比4大,交换位置
- 第二次排序:4 3 5 2 1 6 5和3比较,5比3大,交换位置
- 第三次排序:依上面步骤重复…
Debug分析
通过Debug调试的方式进行算法的分析。
- 首先在变量
count一行打上一个断点

- 然后点击
按钮进入调试状态,界面如下图

- 然后再通过
Step Over按钮
进行逐行调试,点击之后首先进入外层for循环中。

可以看到此时数组中的值没有任何变化,仍然是存储的几个数值。
- 接下来再点击
Step Over进入内层for循环

此时已然没有任何变化,仍是数组中的初始值
- 下面再继续
Step Over进入判断条件,如果arrays[j] > arrays[j + 1]才能继续执行.

进入判断条件之后可以看到,6元素比5大,继续往下执行

这一行是将前一位元素的值交给临时变量
count,此时的arrays[j]值为6.

- 继续
Step Over往下执行

这一步再将
arrays[j + 1],也就是向后进一位的元素,此时为5。赋值给后一位元素6
- 最后一步通过把
count值赋给arrays[j + 1],进行元素的交换。

这一步中0号元素和1号元素都变成了5,是因为经过了这一步
arrays[j] = arrays[j + 1],在这之前0号元素已经被后一位元素赋值。
- 继续往下执行,跳出当前内循环,交换两个元素的位置,第一轮的第一次排序完成。

按照以上
Debug的方式一步一步执行,直到6到大最顶层为止才跳出当前内循环,然后进行下一轮的最大元素排序。
下图为第一次排序完成后的结果,最大元素6已经浮至上层。
- 在第一次排序完成后,如果此时继续
Step Over下一步,则直接跳到外层循环,接着下一次的元素排序。

注:下一轮排序从5开始。
下面是显示五轮排序的详细代码,通过在外层内循环定义一个循环,打印出每一轮的排序结果。
public static void main(String[] args) {int[] arrays = { 6,5,4,3,2,1 };System.out.println("排序之前" + Arrays.toString(arrays));int count = 0;for(int i = 0; i < arrays.length -1; i++) {for(int j =0; j < arrays.length -i -1; j++) {if(arrays[j] > arrays[j + 1]) {count = arrays[j];arrays[j] = arrays[j + 1];arrays[j + 1] = count;}}System.out.print("第" + (i + 1) + "次排序结果:");for (int array : arrays) {System.out.print("\t" + array);}System.out.println("");}}
打印结果

