Java实现冒泡排序以及一种优化方式

来源:互联网 发布:广州网络女装批发市场 编辑:程序博客网 时间:2024/05/16 11:30

1 冒泡排序

冒泡排序是排序算法中常见的、也是非常基本的一种算法,在平常的学习工作中都会用到,尤其是在找工作面试的时候,算法方面排序算法几乎都会问到。

排序算法的实质上就是在数组中,相邻的两个数互相比较,按照大小排序交换位置,以此类推。大致思路如下:

  • 从数组中的第一个数和第二个数开始,比较数组中相邻两个数的大小,并且按照大小排序不同,交换位置
  • 在第一轮比较之后,开始第二轮比较
  • 一轮数据比较之后,没有发生数据位置交换,则认为排序完成

注意: 网上能够看到很多冒泡排序算法的算法过程、时间复杂度等内容,这里不做记录,主要记录实现方法。


2 Java代码实现

下面为一种实现方法,注意代码实现的是从小到大的顺序排序:

   public static String printArray(int[] arr){        StringBuilder strBuider = new StringBuilder();        for(int i=0;i<arr.length;i++){            strBuider.append(arr[i]+",");        }        return strBuider.toString();    }    public static void bubbleSort(int[] arr){        int temp = 0;//临时中间数,用于交换数据        for(int i=0;i<arr.length-1;i++){//最坏的情况(倒序排列),循环比较arr.length趟            for(int j =0;j<arr.length-1-i;j++){//arr.length-1-i:第一趟排序完成之后,最大的数肯定在最后,第二轮排序完成之后,第二大的数肯定在倒数第二,以此类推,所以后面排好序了的不需要再比较排序。                if(arr[j]>arr[j+1]){//从小到大排序                    temp = arr[j];                    arr[j] = arr[j+1];                    arr[j+1] = temp;                }            }            System.out.println("第"+(i+1)+"趟排序结果:"+printArray(arr));        }        System.out.println("最终结果:"+printArray(arr));    }

测试代码与运行结果:

  • 测试1
    数组:int[] arr = {12,2,34,23,56,37,26,1,11,22,33,55,13,8,24};
public static void main(String[] args){        int[] arr = {12,2,34,23,56,37,26,1,11,22,33,55,13,8,24};        BubbleSort.bubbleSort(arr);    }
  • 运行结果
第1趟排序结果:2,12,23,34,37,26,1,11,22,33,55,13,8,24,56,第2趟排序结果:2,12,23,34,26,1,11,22,33,37,13,8,24,55,56,第3趟排序结果:2,12,23,26,1,11,22,33,34,13,8,24,37,55,56,第4趟排序结果:2,12,23,1,11,22,26,33,13,8,24,34,37,55,56,第5趟排序结果:2,12,1,11,22,23,26,13,8,24,33,34,37,55,56,第6趟排序结果:2,1,11,12,22,23,13,8,24,26,33,34,37,55,56,第7趟排序结果:1,2,11,12,22,13,8,23,24,26,33,34,37,55,56,第8趟排序结果:1,2,11,12,13,8,22,23,24,26,33,34,37,55,56,第9趟排序结果:1,2,11,12,8,13,22,23,24,26,33,34,37,55,56,第10趟排序结果:1,2,11,8,12,13,22,23,24,26,33,34,37,55,56,第11趟排序结果:1,2,8,11,12,13,22,23,24,26,33,34,37,55,56,第12趟排序结果:1,2,8,11,12,13,22,23,24,26,33,34,37,55,56,第13趟排序结果:1,2,8,11,12,13,22,23,24,26,33,34,37,55,56,第14趟排序结果:1,2,8,11,12,13,22,23,24,26,33,34,37,55,56,最终结果:1,2,8,11,12,13,22,23,24,26,33,34,37,55,56,
  • 测试2
    数组:int[] arr = {12,11,16,17,18,19};
public static void main(String[] args){        int[] arr = {12,11,16,17,18,19};        BubbleSort.bubbleSort(arr);    }
  • 运行结果
第1趟排序结果:11,12,16,17,18,19,第2趟排序结果:11,12,16,17,18,19,第3趟排序结果:11,12,16,17,18,19,第4趟排序结果:11,12,16,17,18,19,第5趟排序结果:11,12,16,17,18,19,最终结果:11,12,16,17,18,19,

注意:这中实现方式能够正确的排序出结果,但是注意到,其实正确结果到第11趟就已经完成,所以后面的几趟排序比较是不需要的。出现后面多余的比较的原因是,在外层循环中,条件为i<arr.length-1,所以无论结果何时完成,都会进行array.length此排序。


3 常见的一种优化方式

由上面的结果中,我们容易想到,如果一个数组长度为n的数据只需要交换一次就能够排序出结果的话(如测试2),根本不需要循环n次。最外层循环控制了总的循环比较次数,所以,优化冒泡排序,优化最外层循环是一个不错的思路。

下面的优化方式为:最外层循环由while控制,加一个交换数据的标志符号exchange,若数据发生交换,则继续循环排序,若数据没有发生交换,则排序完成,退出循环。实现代码如下:

public static void bubbleSort3(int[] arr){        int temp = 0;        int i = 1;//排序趟数        boolean exchange = true;//外层循环控制        while(exchange){            boolean flag = false;//内部交换标志            for(int j=0;j<arr.length-1;j++){                if(arr[j]>arr[j+1]){//从小到大排序                    temp = arr[j];                    arr[j] = arr[j+1];                    arr[j+1] = temp;                    flag = true;//数据发生交换                }            }            if(!flag){//数据没有发生交换,退出循环                exchange = false;            }else{                System.out.println("第"+i+"趟排序结果:"+printArray(arr));                i++;            }        }        System.out.println("最终结果:"+printArray(arr));    }

测试代码与运行结果:

  • 测试1
    数组:int[] arr = {12,2,34,23,56,37,26,1,11,22,33,55,13,8,24};
public static void main(String[] args){        int[] arr = {12,2,34,23,56,37,26,1,11,22,33,55,13,8,24};        BubbleSort.bubbleSort3(arr);    }
  • 运行结果
第1趟排序结果:2,12,23,34,37,26,1,11,22,33,55,13,8,24,56,第2趟排序结果:2,12,23,34,26,1,11,22,33,37,13,8,24,55,56,第3趟排序结果:2,12,23,26,1,11,22,33,34,13,8,24,37,55,56,第4趟排序结果:2,12,23,1,11,22,26,33,13,8,24,34,37,55,56,第5趟排序结果:2,12,1,11,22,23,26,13,8,24,33,34,37,55,56,第6趟排序结果:2,1,11,12,22,23,13,8,24,26,33,34,37,55,56,第7趟排序结果:1,2,11,12,22,13,8,23,24,26,33,34,37,55,56,第8趟排序结果:1,2,11,12,13,8,22,23,24,26,33,34,37,55,56,第9趟排序结果:1,2,11,12,8,13,22,23,24,26,33,34,37,55,56,第10趟排序结果:1,2,11,8,12,13,22,23,24,26,33,34,37,55,56,第11趟排序结果:1,2,8,11,12,13,22,23,24,26,33,34,37,55,56,最终结果:1,2,8,11,12,13,22,23,24,26,33,34,37,55,56,

用相同的数组比较,比优化之前的测试1少了几次排序,提高了效率。

  • 测试2
    数组:int[] arr = {12,11,16,17,18,19};
public static void main(String[] args){        int[] arr = {12,11,16,17,18,19};        BubbleSort.bubbleSort3(arr);    }
  • 运行结果
第1趟排序结果:11,12,16,17,18,19,最终结果:11,12,16,17,18,19,

这种只需一次交换完成的,明显效率提升了不少,减少了比较交换次数