算法步骤:
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完 后,最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
以下是冒泡算法的具体实现及其改进算法
public class Bubbling {
public static void main(String[] args) {
int[] a={5,8,6,3,9,2,1};
long time1=System.nanoTime();
bubble1(a);
long time2=System.nanoTime();
System.out.println(time2-time1);
int[] b={5,8,6,3,9,2,1};
long time3=System.nanoTime();
bubble2(b);
long time4=System.nanoTime();
System.out.println(time4-time3);
int[] c={5,8,6,3,9,2,1};
long time5=System.nanoTime();
bubble2(c);
long time6=System.nanoTime();
System.out.println(time6-time5);
}
//冒泡排序一之基础算法
public static void bubble1(int[] a){
for (int i=0;i<a.length-1;i++){
for (int j=0;j<a.length-1;j++){
if (a[j]>a[j+1]){
int tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
}
}
}
for (int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
}
//冒泡排序二之改进算法一
//在外层循环内加一个flag判断,如果内层循环发生了交换则说明数组无序,将flag置
//为true,否则flag为false,若flag为false则说明数组以经有序,后面不需要再做余的交换
public static void bubble2(int[] a){
for (int i=0;i<a.length-1;i++){
//有序标记,每一轮的初始是true
boolean flag=true;
for (int j=0;j<a.length-1;j++){
if (a[j]>a[j+1]){
int tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
flag=true;
}
}
if (!flag){
break;
}
}
for (int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
}
//冒泡排序三之改进算法二
//为无序的数列设置一个边界,每次比较到边界即可,后面的为有序数列,无序比较
private static void bubble3(int[] a){
int tmp = 0;
//记录最后一次交换的位置
int lastExchangeIndex = 0;
//无序数列的边界,每次比较只需要比到这里为止
int sortBorder = a.length - 1;
for(int i = 0; i < a.length; i++)
{
//有序标记,每一轮的初始是true
boolean flag = true;
for(int j = 0; j < sortBorder; j++)
{
if(a[j] > a[j+1])
{
tmp = a[j];
a[j] = a[j+1];
a[j+1] = tmp;
//有元素交换,所以不是有序,标记变为false
flag = false;
//把无序数列的边界更新为最后一次交换元素的位置
lastExchangeIndex = j;
}
}
sortBorder = lastExchangeIndex;
if(flag){
break;
}
}
for (int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
}
}
经测试:
1 2 3 5 6 8 9
用时:669006
1 2 3 5 6 8 9
用时:158620
1 2 3 5 6 8 9
用时:125497
改进后的算法较之前的用时有明显降低