冒泡排序【BubbleSort】

冒泡排序

假设初始的数组是[5,4,7,2] 以从小到大排序为例:

  1. 将第0个元素与第一个元素进行比较, 5 > 4, 所以交换位置, 此时[4,5,7,2]
  2. 将第1个元素与第二个元素进行比较, 5 < 7, 所以保持,此时[4,5,7,2]
  3. 将第2个元素与第三个元素进行比较, 7 > 2, 所以交换位置, 此时[4,5,2,7]

这样就经过了一轮的冒泡,最后一个元素就是最大的元素了。
根据相同的方法,开始第2轮的排序,再次从第0个元素开始,两两比较,此时不再让最后一个元素来参与比较了,因为它已经是最大值了。

总结起来:
1. 将相邻的元素两两看作一对。如果第一个比第二个大,就交换他们两个。
2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。完成一次后,最后的元素会是最大的数。
3. 针对所有的元素重复以上的步骤,除了后面已经排好序的元素,直到没有任何一对数字需要比较

算法实现

public class BubbleSort {

    public void bubbleSort(int[] arr) {
        if(arr == null) {
            return ;
        }
        for(int i = arr.length - 1; i > 0; i--) {
            for(int j = 0; j < i; j++) {
                if(arr[j] > arr[j+1]) {
                    swap(arr, j, j + 1);
                }
            }
        }
    }

    private void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp; 
    }
}

时间复杂度

不考虑初始化数据的情况,需要进行n-1次排序(n为数组长度),每一次排序需要进行n-i次比较(i为当前第几次排序)。所以时间复杂度为 O(N^2)

如果考虑数据情况,比如一开始数组就是排好序的,那么在上面的算法中加入一个标志位,一开始标志位为false,当进行过数据交换后,就将标志位变成true,当完成一次排序后,检查下标志位,如果还是为false,就表明整个数组不再需要交换位置了,此时时间复杂度变为 O(N)。 但是这只是特殊情况而已,不做参考。

稳定性

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

通俗地讲就是是否能保证排序前两个相等的数据其在序列中的先后位置顺序与排序后它们两个先后位置顺序相同。

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

猜你喜欢

转载自blog.csdn.net/u013435893/article/details/79968588