排序算法(一):冒泡排序

目录

一、算法原理

二、算法改进

三、算法分析

四、算法实现


一、算法原理

冒泡排序算法的原理如下:

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。

  2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。一趟排序之后,最后的元素应该会是最大的数。

  3. 针对所有的元素重复以上的步骤,除了最后一个(最后一个已经有序)。

  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

示例演示:

待排序数组int[] arr = {3,7,2,8,4}; ,对数组升序排序。(红色为有序)

第一趟排序结果:3,2,7,4,8(四次比较)

Ⅰ、3,7比较=》3,7;

Ⅱ、7,2比较=》3,2,7;

Ⅲ、7,8比较=》3,2,7,8;

Ⅳ、8,4比较=》3,2,7,4,8

第二趟排序结果:2,3,4,7,8(三次比较)

Ⅰ、3,2比较=》2,3;

Ⅱ、3,7比较=》2,3,7;

Ⅲ、7,4比较=》3,2,4,7

第三趟排序结果:2,3,4,7,8(两次比较)

Ⅰ、2,3比较=》2,3;

Ⅱ、3,4比较=》2,3,4

第四趟排序结果:2,3,4,7,8(一次比较)

Ⅰ、2,3比较=》2,3

二、算法改进

       从开头的示例中可以看到,数组在第二趟排序结束之后,就已经有序,排序不需要再进行。观察规律,发现当数组已经有序时,比较时就不会再发生交换。

       所以可以设置标记swapFlag=false,在每次比较中,如果发生交换,将swapFlag置为true;没发生交换,swapFlag仍为false。每一趟排序结束后,先判断swapFlag的值,如果为false,则数组已经有序,跳出循环结束排序;否则进行下一趟排序。

(参考“四、算法实现”阅读)

三、算法分析

1、时间复杂度分析

       1)如果我们的数据已经有序,只需要走一趟即可完成排序。所需的比较次数C和记录移动次数M均达到最小值,即:Cmin=n-1;Mmin=0;所以,冒泡排序最好的时间复杂度为O(n)。

       2)如果数组完全反序,则需要进行n-1趟排序。每趟排序要进行n-i次比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:

C_{max}=\frac{n(n-1))}{2}=O(n^{2})

M_{max}=\frac{3n(n-1))}{2}=O(n^{2})

所以冒泡排序的最坏时间复杂度为:O(n2) 。

综上所述:冒泡排序总的平均时间复杂度为:O(n2) 。

2、算法稳定性分析

        排序算法稳定性定义:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。

      冒泡排序只有当前面元素大于后面元素时,才会进行交换,即,两个元素相等,不会进行交换,相对位置也就不会更改,所以冒泡排序是稳定的排序算法。

四、算法实现

1、冒泡排序算法实现

语言:Java   环境:JDK1.8

    public static void bubbleSort(int[] array) {
        int length = array.length;
        //表示排序趟数,一共array.length-1次。
        for (int i = 0; i < length - 1; i++) {
            for (int j = 0; j < length - 1 - i; j++) {
                if (array[j] > array[j + 1]) {
                    //将大值交换到后边
                    int temp = array[j + 1];
                    array[j + 1] = array[j];
                    array[j] = temp;
                }
            }
        }
    }

2、冒泡排序算法(改进)实现

语言:Java   环境:JDK1.8

    public static void bubbleSort1(int[] array) {
        int length = array.length;
        //交换标志
        boolean swapFlag = false;
        for (int i = 0; i < length - 1; i++) {
            swapFlag = false;
            for (int j = 0; j < length - 1 - i; j++) {
                if (array[j] > array[j + 1]) {
                    int temp = array[j + 1];
                    array[j + 1] = array[j];
                    array[j] = temp;
                    if(!swapFlag){
                        swapFlag = true;
                    }
                }
            }
            //没发生交换退出循环
            if (!swapFlag) {
                break;
            }
        }
    }

 

你可能感兴趣的:(#,排序算法)