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

一、冒泡排序介绍

冒泡排序的算法是最经典的排序算法。

根据上图,我们可以总结排序原理如下:

1. 比较相邻的元素,如果前一个元素比后一个大,就交换这两个元素的位置。

2. 对每一对儿相邻的元素做同样的操作,从第一对元素到结尾的最后一对元素,最终最后位置的元素就是最大值。

二、冒泡排序代码实现

import java.util.Arrays;

/**
 * 冒泡排序算法
 */
public class BubbleSort {

    public static void main(String[] args) {
        Integer[] arr = {4, 5, 3, 9, 2, 1};
        sort(arr);
        System.out.println(Arrays.asList(arr).toString());
    }

    public static void sort(Comparable[] a) {
        for (int i = a.length - 1; i > 0; i--) {
            for (int j = 0; j < i; j++) {
                if (greater(a[j], a[j + 1])) {
                    exch(a, j, j + 1);
                }
            }
        }
    }

    private static boolean greater(Comparable i, Comparable j) {
        return i.compareTo(j) > 0;
    }

    public static void exch(Comparable[] a, int i, int j) {
        Comparable temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}

输出结果:

[1, 2, 3, 4, 5, 9]

三、冒泡排序时间复杂度分析

因为冒泡排序使用的双层for循环,内层循环负责真正的排序工作。所以分析冒泡排序诉法的时间复杂度,主要分析内层循环体的执行次数即可。

最坏的情况下,元素比较的次数为 (N-1) + (N-2) +(N-3)  +...+ 1 = N^2/2-N/2,元素交换的次数为  (N-1) + (N-2) +(N-3)  +...+ 1 = N^2/2-N/2;总执行次数为N^2-N。

按照大O推导法则,可得知冒泡排序的时间复杂度为O(n^2)。

四、适用场景及算法优化

1. 适用场景

冒泡排序适用于元素较少的排序场景。

2. 算法优化

假设我们现在排序ar[]={1,2,3,4,5,6,7,8,10,9}这组数据,按照上面的排序方式,第一趟排序后将10和9交换已经有序,接下来的8趟排序就是多余的,什么也没做。

所以我们可以在交换的地方加一个标记,如果那一趟排序没有交换元素,说明这组数据已经有序,不用再继续下去。

代码修改Sort()方法如下:

public static void sort(Comparable[] a) {
    for (int i = a.length - 1; i > 0; i--) {
        boolean hasAllSorted = true;
        for (int j = 0; j < i; j++) {
            if (greater(a[j], a[j + 1])) {
                exch(a, j, j + 1);
                hasAllSorted = false;
            }
        }
        if (hasAllSorted) {
            return;
        }
    }
}

虽然优化减少了部分无意义的循环次数,但是时间复杂度未变,仍然是O(n^2)。

 

posted @ 2020-05-12 15:14  灰色飘零  阅读(251)  评论(0)    收藏  举报