排序-冒泡排序

138 阅读3分钟

1.1 基本思想

冒泡排序(Bubble Sort)是一种简单的排序算法,它通过多次遍历待排序的序列,每次比较相邻的元素,如果它们的顺序错误,就交换它们的位置。这样,每一轮遍历都会把当前未排序部分中最大的元素"冒泡"到序列的末尾。重复这个过程,直到整个序列有序。

1.2 算法描述

冒泡排序算法的算法过程如下:

比较相邻元素:从序列的开始位置,依次比较相邻的两个元素。

交换元素:如果当前元素比下一个元素大,则交换它们的位置。

重复步骤:每一轮遍历会将当前未排序部分中最大的元素"冒泡"到序列的末尾,下一轮只需要排序剩余的部分。

停止条件:当没有需要交换的元素时,排序完成,可以提前结束排序。

1.3 代码实现

public class BubbleSort {

    /**
     * 冒泡排序
     *
     * @param array 数组
     */
    public static void bubbleSort(int[] array) {
        // 变量记录是否发生交换
        boolean change;
        for (int i = 0; i < array.length - 1; i++) {
            change = false;
            for (int j = 0; j < array.length - 1 - i; j++) {
                if (array[j] > array[j + 1]) {
                    swapByTemp(array, j, j + 1);
                    change = true;
                }
            }
            // 如果没有发生交换,则说明已经排好序,可以提前退出
            if (!change) {
                return;
            }
        }
    }

    /**
     * 通过临时变量交换数组array的i和j位置的数据
     *
     * @param array 数组
     * @param i     下标i
     * @param j     下标j
     */
    public static void swapByTemp(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    /**
     * 通过算术法交换数组array的i和j位置的数据
     *
     * @param array 数组
     * @param i     下标i
     * @param j     下标j
     */
    public static void swapByArithmetic(int[] array, int i, int j) {
        // 有可能溢出
        array[i] = array[i] + array[j];
        // array[j] 已经成为了原 array[i]
        array[j] = array[i] - array[j];
        // array[i] 已经成为了原 array[j]
        array[i] = array[i] - array[j];
    }


    /**
     * 通过位运算法交换数组array的i和j位置的数据
     *
     * @param array 数组
     * @param i     下标i
     * @param j     下标j
     */
    public static void swapByBitOperation(int[] array, int i, int j) {
        // array[i] 被 array[j] 异或一次
        array[i] = array[i] ^ array[j];
        // array[i] 被 array[j] 异或两次 还原成 原 array[i] 此时 array[j] 已经成为了原 array[i]
        // array[i] ^ array[j] ^ array[j] = array[i]
        array[j] = array[i] ^ array[j];
        // array[j] 现在就是原 array[i]
        // array[i] ^ array[j] ^ array[i] = array[j]
        array[i] = array[i] ^ array[j];
    }
}

冒泡排序是稳定的排序算法,最容易实现的排序。最坏的情况是当序列是逆序时,每个元素都需要与其他元素进行比较和交换。 共需遍历并交换将近n²/2次, 时间复杂度为O(n²)。 最佳的情况是序列已经是有序的,冒泡排序只需要遍历一次就能结束,时间复杂度为O(n)。 平均来讲 ,时间复杂度为O(n²)。 因为冒泡排序是就地排序,不需要额外的存储空间, 因此空间复杂度为常量O(1)。

平均时间复杂度最好情况最坏情况空间复杂度
O(n2)O(n)O(n2)O(1)

补充:稳定排序算法

所谓稳定,指的是当数组中出现相同数值元素的时候,排序是否会造成相同数值元素相对位置的改变。可以看出在冒泡排序算法中,对于相同数值的元素我们并没有进行比较和交换位置,所以相同数值元素的相对位置不会发生改变,因此冒泡排序算法是稳定的排序算法。