一、什么是冒泡排序?
我的理解:冒泡排序的精髓在于两两相邻的元素相互比较,如果两个数据本身按照从小到大排,那么这两个元素位置就是正确的,不用互换,反之互换这两个元素。然后继续这两个元素的后一个元素与第三个元素比较,看是否需要互换位置,依次类推,完成第一次的冒泡排序,这时候最大的元素已经到了最后的位置。然后再进行下一次冒泡排序,这个时候最后一个元素就不参加比较了,其余的按照上面的步骤依次进行,直到排序完成。
具体的可以见以下视频链接:
冒泡排序视频详解
二、Java算法实现
import java.lang.reflect.Array;
import java.util.Arrays;
/**
* 冒泡排序需要实现的方法包括:
* 1--比较元素大小
* 2--互换位置
* 3--排序,先比较大小,再考虑是否互换位置
* 其中需要注意冒泡排序的次数为元素的个数-1
*/
//实现Comparable接口
class BubbleSort {
//比较算法,如果大于零,表示a比b大.
// 注意Comparable接口类型可能让人能疑惑,
// 请记住父类接口指向子类实例,就懂了,类/接口是可以作为类型的
public static boolean comparing(Comparable a,Comparable b){
return a.compareTo(b)>0;
}
//交换算法,要有一个临时变量进行传递
public static void exchange(Comparable[]arr,int i,int j){
Comparable temp;
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
//排序
public static void sort(Comparable[]arr){
// 第一层循环,表示要多少次冒泡排序
for (int i=0;i<arr.length-1;i++){
// 第二层循环,每次冒泡排序两两互换的次数
//关于这两层循环的理解可参考下面的第三部分内容
for (int j=0;j<arr.length-i-1;j++){
if(comparing(arr[j],arr[j+1])){
exchange(arr,j,j+1);
}
}
}
}
}
public class Test{
public static void main(String[] args) {
// 定义一个数组
Integer[]arr={6,5,4,7,1,70,9,0};
System.out.println("排序前的数组:"+Arrays.toString(arr));
// 调用方法,注意是静态方法,可以这样调用
BubbleSort.sort(arr);
System.out.println("排序前的数组:"+Arrays.toString(arr));
}
}
结果:
三、冒泡排序两层循环的理解
1、内层循环
先从内层循环开始理解,内层循环就是我们每次冒泡排序的情况,思考这样一个问题,有n个元素的数组,需要依次两两比较多少次?
答案是n-1次,所以内层循环就应该是:for (int j=0;j<n-1;j++),注意这里有一点需要注意,那么就是因为我们有多次冒泡,每次冒泡之后,下次冒泡就不会在将上次冒泡得到的最大的值包含在其中进行第二次冒泡的比较,所以我们的n-1应该是变化的,准确的说是n是变化的,就是参与比较的元素的个数的变化的,而这个变化就和冒泡的次数相关,每冒泡一次,n就应该减1,冒泡i次,n就要减i,而这个冒泡次数就和外层循环有关了。
2、外层循环
外层循环表示冒泡的次数,思考这样一个问题,有n个元素的数组,需要冒泡多少次?答案是n-1次,每次冒泡就是将剩下的最大的值放到最后,第一次,把最大的放到最后,第二次把第二大的放到倒数第二个,第n-1次,把倒数第二大的放到第二个位置,此时冒泡已经完成,因为最小的数就是在第一个位置了。所以外层循环就应该是:for (int i=0;i<arr.length-1;i++),这里arr.length就是数组元素个数n,在冒泡次数确定的情况下,内层循环就可以变为:for (int j=0;j<arr.length-i-1;j++)。
更多可以参考以下链接:
冒泡排序双层循环的理解