2.1 冒泡排序:最直观的排序思想

历史背景

冒泡排序是最古老的排序算法之一,其思想可以追溯到 20 世纪 50 年代计算机科学的早期。1956 年,计算机科学家兼海军军官 Harry H. Goode 在一篇论文中描述了类似冒泡排序的算法。由于其简单直观的特性,冒泡排序成为几乎所有编程入门教材中首先介绍的排序算法。它得名于排序过程中较大的元素会像气泡一样逐渐"浮"到数组的顶端。

算法原理

冒泡排序的基本思想是:重复地遍历要排序的数组,依次比较相邻的两个元素,如果它们的顺序错误(前一个大于后一个)就交换它们的位置。每一轮遍历都会将当前未排序部分的最大元素"冒泡"到正确的位置。经过 n-1 轮遍历后,整个数组就有序了。

Java 实现

java
复制代码
public class BubbleSort {
    
    /**
     * 冒泡排序(基础版本)
     * @param arr 待排序的整数数组
     */
    public static void sort(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    // 交换相邻元素
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }
    
    /**
     * 冒泡排序(优化版本)
     * 添加提前终止标志,当某一轮没有发生交换时说明数组已经有序
     * @param arr 待排序的整数数组
     */
    public static void sortOptimized(int[] arr) {
        int n = arr.length;
        boolean swapped;
        for (int i = 0; i < n - 1; i++) {
            swapped = false;
            for (int j = 0; j < n - 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;
            }
        }
    }
    
    /**
     * 冒泡排序(泛型版本)
     * 支持任何实现了 Comparable 接口的类型
     */
    public static <T extends Comparable<T>> void sortGeneric(T[] arr) {
        int n = arr.length;
        boolean swapped;
        for (int i = 0; i < n - 1; i++) {
            swapped = false;
            for (int j = 0; j < n - 1 - i; j++) {
                if (arr[j].compareTo(arr[j + 1]) > 0) {
                    T temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    swapped = true;
                }
            }
            if (!swapped) {
                break;
            }
        }
    }
}

效率分析

指标 最好情况 最坏情况 平均情况
时间复杂度 O(n)(优化版) O(n²) O(n²)
空间复杂度 O(1) O(1) O(1)
比较次数 n-1 n(n-1)/2 n(n-1)/4
交换次数 0 n(n-1)/2 n(n-1)/4

冒泡排序是稳定的排序算法,也是原地排序算法。它的优点是实现极其简单,且优化版能够检测到已经有序的数组并提前终止。缺点是效率太低,对于大规模数据完全不可用。

应用场景

  • 教学演示排序算法的基本概念
  • 数据量极小(n < 100)的场景
  • 数据基本有序的场景(优化版表现较好)
  • 嵌入式系统等资源极度受限的环境