冒泡排序算法原理与Java实现

在编程中,排序是一项基础且常见的任务。冒泡排序(Bubble Sort)是最简单的排序算法之一,其核心思想是通过重复比较相邻元素并交换位置,使较大的元素“冒泡”到数组末尾(升序排序时),或较小的元素“冒泡”到数组开头(降序排序时)。

排序步骤解析

以数组 [5, 2, 9, 1, 5] 为例,演示升序排序过程:

  1. 第一轮(未排序部分:[5,2,9,1,5]
    - 比较 525 > 2,交换 → [2,5,9,1,5]
    - 比较 595 < 9,不交换
    - 比较 919 > 1,交换 → [2,5,1,9,5]
    - 比较 959 > 5,交换 → [2,5,1,5,9]
    - 结果:最大元素 9 已“冒泡”到末尾,未排序部分变为 [2,5,1,5]

  2. 第二轮(未排序部分:[2,5,1,5]
    - 比较 252 < 5,不交换
    - 比较 515 > 1,交换 → [2,1,5,5]
    - 比较 555 = 5,不交换
    - 结果:第二大元素 5 已“冒泡”到倒数第二位,未排序部分变为 [2,1,5]

  3. 第三轮(未排序部分:[2,1,5]
    - 比较 212 > 1,交换 → [1,2,5]
    - 比较 252 < 5,不交换
    - 结果:第三大元素 5 已“冒泡”到倒数第三位,未排序部分变为 [1,2]

  4. 第四轮(未排序部分:[1,2]
    - 比较 121 < 2,不交换
    - 结果:排序完成,数组变为 [1,2,5,5,9]

Java代码实现

public class BubbleSort {
    /**
     * 冒泡排序算法实现(升序)
     * @param arr 待排序的数组
     */
    public static void bubbleSort(int[] arr) {
        // 外层循环:控制排序轮数(最多n-1轮)
        for (int i = 0; i < arr.length - 1; i++) {
            boolean swapped = false; // 优化标记:本轮是否发生交换
            // 内层循环:控制每轮比较次数(已排好序的元素无需再比较)
            for (int j = 0; j < arr.length - 1 - i; j++) {
                // 若当前元素 > 下一个元素,交换位置
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];       // 临时变量存储当前元素
                    arr[j] = arr[j + 1];     // 交换后一个元素到当前位置
                    arr[j + 1] = temp;       // 交换前一个元素到后一个位置
                    swapped = true;          // 标记本轮发生了交换
                }
            }
            // 若本轮无交换,说明数组已完全有序,提前结束排序
            if (!swapped) {
                break;
            }
        }
    }

    public static void main(String[] args) {
        // 测试数组
        int[] arr = {5, 2, 9, 1, 5};
        System.out.println("排序前:" + java.util.Arrays.toString(arr));

        // 调用冒泡排序
        bubbleSort(arr);

        System.out.println("排序后:" + java.util.Arrays.toString(arr));
    }
}

代码关键点说明

  1. 外层循环:控制排序轮数,共需 arr.length - 1 轮(最后一个元素无需比较)。
  2. 内层循环:每轮比较相邻元素,次数为 arr.length - 1 - ii 为已排好序的元素个数)。
  3. 交换逻辑:使用临时变量 temp 交换相邻元素,确保排序稳定。
  4. 优化技巧:通过 swapped 标记,若某轮无交换,提前终止排序(适用于接近有序的数组)。

时间与空间复杂度

  • 时间复杂度
  • 最坏情况(完全逆序):O(n²)(需完整执行所有轮次)。
  • 平均情况:O(n²)
  • 最好情况(已排序):O(n)(优化后通过 swapped 标记提前终止)。
  • 空间复杂度O(1)(仅需临时变量,原地排序)。

总结

冒泡排序原理简单直观,适合初学者理解排序核心思想。但由于时间复杂度较高(O(n²)),实际应用中较少用于大规模数据,通常用于教学或小规模数据排序场景。掌握后可进一步学习更高效的排序算法(如快速排序、归并排序等)。

小夜