冒泡排序原理分析及Java实现

排序是将一组数据按照一定的规则进行排列,一般按递增或者递减的顺序来排列。可以分为基本排序和多路归并排序。基本排序又可以分为交换排序(冒泡排序、快速排序)、插入排序(插入排序、shell排序)、选择排序(选择排序、堆排序)以及合并排序。以上基本排序算法都是直接对计算机内存中的数据进行排序,但对于一些打文件,不能直接将文件读入内存中排序时,我们可以将文件划分为几个可以读入内存中的小文件,分别对入内存中进行排序,经过多次处理后便可完成大文件的排序。

冒泡排序:
冒泡排序算法是所有排序算法中最简单、最基本的一种,通过相邻数据的交换来达到排序的目的。冒泡排序算法对于N个数进行排序时,无论原来的数据有无顺序,都要进行N-1步的中间排序。这种方法的思路简单直观,缺点是执行的步骤有点长,效率低。

算法原理
1.冒泡排序算法的运作如下:(从后往前)
2.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
3.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
4.针对所有的元素重复以上的步骤,除了最后一个。
5.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

冒泡排序原理分析及Java实现_第1张图片

时间复杂度
若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数C和记录移动次数N均达到最小值: Cmin=n-1,Mmin=0。
所以,冒泡排序最好的时间复杂度为O(n)。
若初始文件是反序的,需要进行n-1趟排序。每趟排序要进行n-i次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录3次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:Cmax=n(n-1)/2=O(n^2)
Mmax=3n(n-1)/2=O(n^2)
冒泡排序的最坏时间复杂度为O(n^2)。
综上,因此冒泡排序总的平均时间复杂度为O(n^2)。

算法稳定性
冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

代码:

 public class Demo {
    static final int SIZE = 10;

    public static void bubbleSort(int[] a) {
        int temp;
        for (int i = 1; i < a.length; i++) {
            // 将相邻两个数进行比较,较大的数往后冒泡
            temp = 0;
            for (int j = 0; j < a.length - i; j++) {
                if (a[j] > a[j + 1]) {
                    // 交换相邻两个数
                    temp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = temp;
                    temp = 1;// 这个地方temp可以作为状态标志,看是否有两数交换
                }
            }
            if (temp == 0)// 如果一趟循环没有两个数发生交换,则说明数组已经有序了,此时退出循环
                break;
            System.out.print("第" + i + "步排序结果:"); // 输出每步排序的结果
            for (int k = 0; k < a.length; k++) {
                System.out.print(" " + a[k]); // 输出
            }
            System.out.print("\n");
        }
    }

    public static void main(String[] args) {
        int[] shuzu = new int[SIZE];
        int i;
        for (i = 0; i < SIZE; i++) {
            shuzu[i] = (int) (100 + Math.random() * (100 + 1)); // 初始化数组
        }
        System.out.print("排序前的数组为:\n"); // 输出排序前的数组
        for (i = 0; i < SIZE; i++) {
            System.out.print(shuzu[i] + " ");
        }
        System.out.print("\n");
        bubbleSort(shuzu); // 排序操作
        System.out.print("排序后的数组为:\n");
        for (i = 0; i < SIZE; i++) {
            System.out.print(shuzu[i] + " "); // 输出排序后的数组
        }
        System.out.print("\n");
    }
    }

上面是优化后的冒泡排序算法,我们把temp当作一个状态标志,当一次中间排序完成,也就是内部的for循环完一次之后需要判断数组是否有发生数据交换(有数据交换时temp=1,没有发生交换时temp=0),如果没有,则说明整个数组已经排序完成,此时退出排序。这样可以减少排序的次数,提高效率,大家可以把temp=1和下面的if判断去掉则是标准的冒泡排序,对比发现效率大大提高。


你可能感兴趣的:(java)