冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序。
这里的介绍有简单到复杂(其实不是复杂了,只是进行了简化和规范而已,其实原理基本相同的)。
首先我们来看下面的程序(我在每行程序上都进行了注释,以便于理解。):
package com.hry.bubble_sort;
import java.util.Arrays;
/**
* @author 侯瑞阳
* java实现冒泡排序算法
*/
public class BubbleSort {
/**
* 定义一个静态的方法方便在主函数中调用
*/
public static void FirstSort(int arr[]) {
// 初始化i为0 因为是数组arr[]是从arr[0]开始的。
int i = 0;
// 输出一句库进行提示
System.out.print("第一趟,第一次排序");
// 循环判断找出最大值,就算不学冒泡排序,我们在学习比较大小的时候也应该会了
if (arr[i] < arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
// 输出排序号之后的结果
System.out.println(Arrays.toString(arr));
}
// 主函数
public static void main(String [] args) {
// 初始化一个数组
int arr[] = {1, 2, 3, 4, 5};
// 调用定义好的静态方法进行排序
FirstSort(arr);
}
}
运行程序输出的结果是:
第一趟,第一次排序[2, 1, 3, 4, 5]
这样以来,我们是不是就进行了一次简单的比较了呢?那么,1 和 3在进行比较之后,是不是1 和 3 交换位置,输出
[2, 3, 1, 4, 5 ] 呢?怎么用程序来实现呢?
如果还不明白的话。我给你一个初始数组是
[ 2, 1, 3, 4, 5 ] 让你来用程序改成[ 2, 3, 1, 4, 5 ] 呢?原来就是上面程序在重复一边呀,那赶紧用 代码来实现下吧!
package com.hry.bubble_sort;
import java.util.Arrays;
/**
* @author 侯瑞阳
* java实现冒泡排序算法
*/
public class BubbleSort {
/**
* 定义一个静态的方法方便在主函数中调用
*/
public static void FirstSort(int arr[]) {
// 初始化i为0 因为是数组arr[]是从arr[0]开始的。
int i = 0;
// 输出一句库进行提示
System.out.print("第一趟,第一次排序");
// 循环判断找出最大值,就算不学冒泡排序,我们在学习比较大小的时候也应该会了
if (arr[i] < arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
// 输出排序号之后的结果
System.out.println(Arrays.toString(arr));
i++;
System.out.print("第一趟,第二次排序");
// 循环判断找出最大值,就算不学冒泡排序,我们在学习比较大小的时候也应该会了
if (arr[i] < arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
// 输出排序号之后的结果
System.out.println(Arrays.toString(arr));
i++;
System.out.print("第一趟,第三次排序");
// 循环判断找出最大值,就算不学冒泡排序,我们在学习比较大小的时候也应该会了
if (arr[i] < arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
// 输出排序号之后的结果
System.out.println(Arrays.toString(arr));
i++;
System.out.print("第一趟,第四次排序");
// 循环判断找出最大值,就算不学冒泡排序,我们在学习比较大小的时候也应该会了
if (arr[i] < arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
// 输出排序号之后的结果
System.out.println(Arrays.toString(arr));
i++;
}
// 主函数
public static void main(String [] args) {
// 初始化一个数组
int arr[] = {1, 2, 3, 4, 5};
// 调用定义好的静态方法进行排序
FirstSort(arr);
}
}
我想有一小部分人估计忘记了在刚开始定义的 i 的变量。可不要忘记在每次执行完毕之后
不要忘记把 i自身加上1 参与下一次运算呀!来看运行结果:
第一趟,第 1 次排序[2, 1, 3, 4, 5]
第一趟,第 2 次排序[2, 3, 1, 4, 5]
第一趟,第 3 次排序[2, 3, 4, 1, 5]
第一趟,第 4 次排序[2, 3, 4, 5, 1]
好了,通过上面的代码我们简单找出了最小值 并放在了数组最后一个位置。那大家有没有发现其实是有很多代码是重复的呢?聪明的人已经想到了解决办法。既然重复,那么我定义一个循环不就解决了吗。下面来看实现代码:
package com.hry.bubble_sort;
import java.util.Arrays;
/**
* @author 侯瑞阳
* java实现冒泡排序算法
*/
public class BubbleSort {
/**
* 定义一个静态的方法方便在主函数中调用
*/
public static void FirstSort(int arr[]) {
// 因为通过之前发现五个数重复执行了四次,所以定义一个整形来控制for循环的次数
int length = arr.length - 1;
for (int i = 0; i < length; i++) {
// 输出一句库进行提示
System.out.print("第一趟,第一次排序");
// 循环判断找出最大值,就算不学冒泡排序,我们在学习比较大小的时候也应该会了
if (arr[i] < arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
// 输出排序号之后的结果
System.out.println(Arrays.toString(arr));
}
}
// 主函数
public static void main(String [] args) {
// 初始化一个数组
int arr[] = {1, 2, 3, 4, 5};
// 调用定义好的静态方法进行排序
FirstSort(arr);
}
}
运行结果:
第一趟,第 1 次排序[2, 1, 3, 4, 5]
第一趟,第 2 次排序[2, 3, 1, 4, 5]
第一趟,第 3 次排序[2, 3, 4, 1, 5]
第一趟,第 4 次排序[2, 3, 4, 5, 1]
有没有发现和之前的一样呢?但是代码是不是减少了很多呢?那么是不是第二趟第三趟第四趟也可以按照这个来实现呢?下面来看实现代码:
package com.hry.bubble_sort;
import java.util.Arrays;
/**
* @author 侯瑞阳
* java实现冒泡排序算法
*/
public class BubbleSort {
/**
* 定义一个静态的方法方便在主函数中调用
*/
public static void FirstSort(int arr[]) {
// 因为通过之前发现五个数重复执行了四次,所以定义一个整形来控制for循环的次数
int length = arr.length - 1;
for (int i = 0; i < length; i++) {
// 输出一句库进行提示
System.out.print("第一趟,第 "+ ( i + 1 ) +" 次排序");
// 循环判断找出最大值,就算不学冒泡排序,我们在学习比较大小的时候也应该会了
if (arr[i] < arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
// 输出排序号之后的结果
System.out.println(Arrays.toString(arr));
}
System.out.println("==============分割线==============");
for (int i = 0; i < length; i++) {
// 输出一句库进行提示
System.out.print("第二趟,第 "+ ( i + 1 ) +" 次排序");
// 循环判断找出最大值,就算不学冒泡排序,我们在学习比较大小的时候也应该会了
if (arr[i] < arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
// 输出排序号之后的结果
System.out.println(Arrays.toString(arr));
}
System.out.println("==============分割线==============");
for (int i = 0; i < length; i++) {
// 输出一句库进行提示
System.out.print("第三趟,第 "+ ( i + 1 ) +" 次排序");
// 循环判断找出最大值,就算不学冒泡排序,我们在学习比较大小的时候也应该会了
if (arr[i] < arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
// 输出排序号之后的结果
System.out.println(Arrays.toString(arr));
}
System.out.println("==============分割线==============");
for (int i = 0; i < length; i++) {
// 输出一句库进行提示
System.out.print("第四趟,第 "+ ( i + 1 ) +" 次排序");
// 循环判断找出最大值,就算不学冒泡排序,我们在学习比较大小的时候也应该会了
if (arr[i] < arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
// 输出排序号之后的结果
System.out.println(Arrays.toString(arr));
}
}
// 主函数
public static void main(String [] args) {
// 初始化一个数组
int arr[] = {1, 2, 3, 4, 5};
// 调用定义好的静态方法进行排序
FirstSort(arr);
}
}
来看运行结果:
第一趟,第 1 次排序[2, 1, 3, 4, 5]
第一趟,第 2 次排序[2, 3, 1, 4, 5]
第一趟,第 3 次排序[2, 3, 4, 1, 5]
第一趟,第 4 次排序[2, 3, 4, 5, 1]
==============分割线==============
第二趟,第 1 次排序[3, 2, 4, 5, 1]
第二趟,第 2 次排序[3, 4, 2, 5, 1]
第二趟,第 3 次排序[3, 4, 5, 2, 1]
第二趟,第 4 次排序[3, 4, 5, 2, 1]
==============分割线==============
第三趟,第 1 次排序[4, 3, 5, 2, 1]
第三趟,第 2 次排序[4, 5, 3, 2, 1]
第三趟,第 3 次排序[4, 5, 3, 2, 1]
第三趟,第 4 次排序[4, 5, 3, 2, 1]
==============分割线==============
第四趟,第 1 次排序[5, 4, 3, 2, 1]
第四趟,第 2 次排序[5, 4, 3, 2, 1]
第四趟,第 3 次排序[5, 4, 3, 2, 1]
第四趟,第 4 次排序[5, 4, 3, 2, 1]
经过四次排序最终一个简单的冒泡排序就完成了。那么细心的同学已经发现了,还是重复了了三次,是不是也可以用循环呢?当然是可以的,下面看代码:
package com.hry.bubble_sort;
import java.util.Arrays;
/**
* @author 侯瑞阳
* java实现冒泡排序算法
*/
public class BubbleSort {
/**
* 定义一个静态的方法方便在主函数中调用
*/
public static void FirstSort(int arr[]) {
int length = arr.length - 1;
for(int j = 0; j < length; j++) {
// 因为通过之前发现五个数重复执行了四次,所以定义一个整形来控制for循环的次数
for (int i = 0; i < length; i++) {
// 输出一句库进行提示
System.out.print("第" + (j + 1 ) + "趟,第 "+ ( i + 1 ) +" 次排序");
// 循环判断找出最大值,就算不学冒泡排序,我们在学习比较大小的时候也应该会了
if (arr[i] < arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
// 输出排序号之后的结果
System.out.println(Arrays.toString(arr));
}
System.out.println("==============分割线==============");
}
}
// 主函数
public static void main(String [] args) {
// 初始化一个数组
int arr[] = {1, 2, 3, 4, 5};
// 调用定义好的静态方法进行排序
FirstSort(arr);
}
}
实现结果:
第1趟,第 1 次排序[2, 1, 3, 4, 5]
第1趟,第 2 次排序[2, 3, 1, 4, 5]
第1趟,第 3 次排序[2, 3, 4, 1, 5]
第1趟,第 4 次排序[2, 3, 4, 5, 1]
==============分割线==============
第2趟,第 1 次排序[3, 2, 4, 5, 1]
第2趟,第 2 次排序[3, 4, 2, 5, 1]
第2趟,第 3 次排序[3, 4, 5, 2, 1]
第2趟,第 4 次排序[3, 4, 5, 2, 1]
==============分割线==============
第3趟,第 1 次排序[4, 3, 5, 2, 1]
第3趟,第 2 次排序[4, 5, 3, 2, 1]
第3趟,第 3 次排序[4, 5, 3, 2, 1]
第3趟,第 4 次排序[4, 5, 3, 2, 1]
==============分割线==============
第4趟,第 1 次排序[5, 4, 3, 2, 1]
第4趟,第 2 次排序[5, 4, 3, 2, 1]
第4趟,第 3 次排序[5, 4, 3, 2, 1]
第4趟,第 4 次排序[5, 4, 3, 2, 1]
==============分割线==============
到此就结束了吗?显然更加细心爱钻研的小伙伴就会发现在“第四趟的第一次排序” 之后结果就已经出来了,后面的不就重复了吗?我为发现这个问题的小伙伴点个赞。那么就会有下面的第二个版本,代码如下:
package com.hry.bubble_sort;
import java.util.Arrays;
/**
* @author 侯瑞阳
* java实现冒泡排序算法
*/
public class BubbleSort {
/**
* 定义一个静态的方法方便在主函数中调用
*/
public static void FirstSort(int arr[]) {
int length = arr.length - 1;
for(int j = 0; j < length; j++) {
// 因为通过之前发现五个数重复执行了四次,所以定义一个整形来控制for循环的次数
// 由于之前的代码存在问题,其解决办法就是在比较次数上做手脚。
for (int i = 0; i < arr.length - 1 - j; i++) {
// 输出一句库进行提示
System.out.print("第" + (j + 1 ) + "趟,第 "+ ( i + 1 ) +" 次排序");
// 循环判断找出最大值,就算不学冒泡排序,我们在学习比较大小的时候也应该会了
if (arr[i] < arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
// 输出排序号之后的结果
System.out.println(Arrays.toString(arr));
}
System.out.println("==============分割线==============");
}
}
// 主函数
public static void main(String [] args) {
// 初始化一个数组
int arr[] = {1, 2, 3, 4, 5};
// 调用定义好的静态方法进行排序
FirstSort(arr);
}
}
运行结果:
第1趟,第 1 次排序[2, 1, 3, 4, 5]
第1趟,第 2 次排序[2, 3, 1, 4, 5]
第1趟,第 3 次排序[2, 3, 4, 1, 5]
第1趟,第 4 次排序[2, 3, 4, 5, 1]
==============分割线==============
第2趟,第 1 次排序[3, 2, 4, 5, 1]
第2趟,第 2 次排序[3, 4, 2, 5, 1]
第2趟,第 3 次排序[3, 4, 5, 2, 1]
==============分割线==============
第3趟,第 1 次排序[4, 3, 5, 2, 1]
第3趟,第 2 次排序[4, 5, 3, 2, 1]
==============分割线==============
第4趟,第 1 次排序[5, 4, 3, 2, 1]
==============分割线==============
这样是不是也能够得出结果,而且比较简单呢?那么这样就结束了吗?显然不是,如果我们排序一次之后就已经得到了我们想要的顺序那么后面的是不是就不用进行了呢?我们来看下面程序帮助我们更好理解:
package com.hry.bubble_sort;
import java.util.Arrays;
/**
* @author 侯瑞阳
* java实现冒泡排序算法
*/
public class BubbleSort {
/**
* 定义一个静态的方法方便在主函数中调用
*/
public static void FirstSort(int arr[]) {
int length = arr.length - 1;
for (int j = 0; j < length; j++) {
// 因为通过之前发现五个数重复执行了四次,所以定义一个整形来控制for循环的次数
// 由于之前的代码存在问题,其解决办法就是在比较次数上做手脚。
for (int i = 0; i < arr.length - 1 - j; i++) {
// 输出一句库进行提示
System.out.print("第" + (j + 1) + "趟,第 " + (i + 1) + " 次排序");
// 循环判断找出最大值,就算不学冒泡排序,我们在学习比较大小的时候也应该会了
if (arr[i] < arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
// 输出排序号之后的结果
System.out.println(Arrays.toString(arr));
}
}
}
public static void FinalSort(int arr[]) {
int length = arr.length - 1;
boolean bool = true;
for (int j = 0; j < length; j++) {
// 因为通过之前发现五个数重复执行了四次,所以定义一个整形来控制for循环的次数
// 由于之前的代码存在问题,其解决办法就是在比较次数上做手脚。
for (int i = 0; i < arr.length - 1 - j; i++) {
// 输出一句库进行提示
System.out.print("第" + (j + 1) + "趟,第 " + (i + 1) + " 次排序");
// 循环判断找出最大值,就算不学冒泡排序,我们在学习比较大小的时候也应该会了
if (arr[i] < arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
bool = false;
}
// 输出排序号之后的结果
System.out.println(Arrays.toString(arr));
}
if (bool) {
break;
}
}
}
// 主函数
public static void main(String [] args) {
int arr[] = {7, 4, 2, 1};
FirstSort(arr);
System.out.println("==============分割线==============");
arr = new int[]{7, 4, 2, 1};
FinalSort(arr);
}
}
运行结果:
第1趟,第 1 次排序[7, 4, 2, 1]
第1趟,第 2 次排序[7, 4, 2, 1]
第1趟,第 3 次排序[7, 4, 2, 1]
第2趟,第 1 次排序[7, 4, 2, 1]
第2趟,第 2 次排序[7, 4, 2, 1]
第3趟,第 1 次排序[7, 4, 2, 1]
==============分割线==============
第1趟,第 1 次排序[7, 4, 2, 1]
第1趟,第 2 次排序[7, 4, 2, 1]
第1趟,第 3 次排序[7, 4, 2, 1]
虽然最后也进行了三趟但是第二种方法显然比第一种还要简单。