简介

  1. 冒泡排序(Bubble Sort)是一种最简单的排序算法,它的实现方法是元素重复访问要排序的值,并且访问过程 中依次比较两个元素,如果顺序(例如从小到大,A-Z)根据算法的不同而出现错误就把它们的位置进行交换,直到元素没有再需要交换的值为止,或者说元素列表已经按从大到小或从小到大排列完成为止,越大的元素会经过算法的交换和比对慢慢浮到元素列的顶端,故名为“冒泡”。

算法描述

  1. 比较相邻的两个元素,如果第一个元素比第二个大,就交换两个元素的位置,例如21,经过排序比较之后就会变成12。
  2. 对元素本身和相邻的元素进行比较,直到结尾为止,最后的元素肯定是最大的数。
  3. 当第一个元素和其它比对完成后,继续从开头元素进行下一轮比较。

冒泡排序实现(Java)

首先贴出Java代码实现冒泡算法的代码。

  1. public class Bubble {
  2. public static void main(String[] args) {
  3. int[] arrays = { 6,5,4,3,2,1 };
  4. System.out.println("排序之前:==> " + Arrays.toString(arrays));
  5. int temp = 0; // 存放临时数据
  6. // 核心代码
  7. for (int i = 0; i < arrays.length - 1; i++) {
  8. for (int j = 0; j < arrays.length -i -1; j++) {
  9. if (arrays[j] > arrays[j + 1]) {
  10. temp = arrays[j];
  11. arrays[j] = arrays[j + 1];
  12. arrays[j + 1] = temp;
  13. }
  14. }
  15. }
  16. System.out.println("排序之后:==>" + Arrays.toString(arrays)); // 调用toString方法打印数组
  17. }
  18. }
  • 打印结果

image.png
从图中可以看到分别打印出了排序前的数值,和排序完之后的数值,由一开始的逆序变为排序后的正序。从而达到正序排序的效果。

冒泡算法分析

首先需要创建一个int类型的数组,并且添加五个数。代表进行排序的元素值

  1. int[] arrays = { 6,5,4,3,2,1 };
  1. 然后定义一个 `count` 变量,作用于存储临时变量,并进行数值的互换。
  1. int count = 0; // 存放临时变量

实现动态排序的效果要先定义一个外层for循环,对arrays数组进行所有值的遍历,这里需要用到.length方法

  1. for (int i = 0; i < arrays.length - 1; i++) {
  2. }

首先在for循环中定义了一个变量i,并且初始值从0开始,i 小于数组的总长度减1,这里的-1指的是最多做n-1次排序。而这一层for循环的意义是指定排序的次数,也就是根据数组中定义的数值个数得出,并且通过.length方法实现。

内部嵌套循环:第二层for循环是进入排序后比较的次数,如果当前比较元素没有可比值则跳出此次内循环

  1. for (int j = 0; j < arrays.length -i -1; j++) {}

同样在循环里定义一个变量 j ,初始值为0开始,并且小于数组的长度,减 i1 ,减 i 操作是防止排序完毕后没有可排序元素时,重复循环一遍的操作,相反减 1 操作是因为初始值是从0开始,避免索引越界。

  1. 接下来就是核心判断的操作,通过内循环的比对进行位置的交换。
  1. // 通过前一位元素和后一位元素进行比较,如果前一位元素比后一位元素值大,就交换两个值的位置。
  2. if (arrays[j] > arrays[j + 1]) {
  3. count = arrays[j]; // 赋值给count变量
  4. arrays[j] = arrays[j + 1]; // 将后+1的后一位元素赋值给前一位元素,
  5. arrays[j + 1] = count; // 将count变量赋值给后一位元素
  6. }

如果前一位元素大于后一位元素才会继续往下走,首先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 一行打上一个断点

image.png

  • 然后点击image.png按钮进入调试状态,界面如下图

image.png

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

image.png

可以看到此时数组中的值没有任何变化,仍然是存储的几个数值。

  • 接下来再点击 Step Over 进入内层for循环

image.png

此时已然没有任何变化,仍是数组中的初始值

  • 下面再继续 Step Over 进入判断条件,如果 arrays[j] > arrays[j + 1] 才能继续执行.

image.png

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

image.png

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

image.png

  • 继续 Step Over 往下执行

image.png

这一步再将 arrays[j + 1] ,也就是向后进一位的元素,此时为5。赋值给后一位元素6

  • 最后一步通过把 count 值赋给 arrays[j + 1] ,进行元素的交换。

image.png

这一步中0号元素和1号元素都变成了5,是因为经过了这一步 arrays[j] = arrays[j + 1] ,在这之前0号元素已经被后一位元素赋值。

  • 继续往下执行,跳出当前内循环,交换两个元素的位置,第一轮的第一次排序完成。

image.png

按照以上 Debug 的方式一步一步执行,直到6到大最顶层为止才跳出当前内循环,然后进行下一轮的最大元素排序。

下图为第一次排序完成后的结果,最大元素6已经浮至上层。
image.png

  • 在第一次排序完成后,如果此时继续 Step Over 下一步,则直接跳到外层循环,接着下一次的元素排序。

image.png

注:下一轮排序从5开始。

下面是显示五轮排序的详细代码,通过在外层内循环定义一个循环,打印出每一轮的排序结果。

  1. public static void main(String[] args) {
  2. int[] arrays = { 6,5,4,3,2,1 };
  3. System.out.println("排序之前" + Arrays.toString(arrays));
  4. int count = 0;
  5. for(int i = 0; i < arrays.length -1; i++) {
  6. for(int j =0; j < arrays.length -i -1; j++) {
  7. if(arrays[j] > arrays[j + 1]) {
  8. count = arrays[j];
  9. arrays[j] = arrays[j + 1];
  10. arrays[j + 1] = count;
  11. }
  12. }
  13. System.out.print("第" + (i + 1) + "次排序结果:");
  14. for (int array : arrays) {
  15. System.out.print("\t" + array);
  16. }
  17. System.out.println("");
  18. }
  19. }

打印结果

image.png