冒泡排序(Bubble Sort)

冒泡排序每一轮只解决一件事:把当前未排序区间里的最大值“顶”到末尾。

定义

冒泡排序是一种简单的排序算法,通过重复遍历待排序序列,比较相邻元素并交换位置,使较大(或较小)的元素逐步”冒泡”到序列末端。

核心思路

  1. 比较相邻的元素,如果顺序错误就交换
  2. 每轮遍历后,最大(或最小)的元素会移动到末尾
  3. 重复以上步骤,直到整个序列有序
第一轮冒泡:[5,3,8,6,2] → [3,5,6,2,8]  (8冒泡到末尾)
第二轮冒泡:[3,5,6,2,8] → [3,5,2,6,8]  (6冒泡到倒数第二)
第三轮冒泡:[3,5,2,6,8] → [3,2,5,6,8]  (5到位)
第四轮冒泡:[3,2,5,6,8] → [2,3,5,6,8]  (完成)

为什么叫“冒泡”

因为大元素会通过一轮轮相邻交换,像气泡一样慢慢浮到右侧末尾。

复杂度分析

指标复杂度说明
最好时间O(n)已排序,只需一轮遍历
平均时间O(n²)需要n轮,每轮平均n/2次比较
最坏时间O(n²)逆序排列
空间复杂度O(1)原地排序
稳定性✅ 稳定相等元素不交换

Go 代码

Go 实现

package main
 
import "fmt"
 
func bubbleSort(arr []int) {
    n := len(arr)
 
    for i := 0; i < n-1; i++ {
        swapped := false
 
        for j := 0; j < n-i-1; j++ {
            if arr[j] > arr[j+1] {
                arr[j], arr[j+1] = arr[j+1], arr[j]
                swapped = true
            }
        }
 
        // 优化:没有交换则提前结束
        if !swapped {
            break
        }
    }
}
 
func main() {
    arr := []int{64, 34, 25, 12, 22, 11, 90}
 
    fmt.Println("原始数组:", arr)
    bubbleSort(arr)
    fmt.Println("排序后:", arr)
}

易错点

冒泡排序很简单,但也最容易把循环边界写得又慢又乱。

  • 第 i 轮结束后,最后 i 个位置已经有序。
  • 内层循环上界应当随着轮次缩短。
  • swapped 优化不能忘,否则几乎有序数组也会白跑很多轮。

算法优化

经典题目

基础应用

变体题目

  • 统计冒泡排序的交换次数
  • 使用冒泡排序找第k大元素
  • 局部有序数组排序

优缺点

优点

  • ✅ 实现简单,易于理解
  • ✅ 稳定排序
  • ✅ 原地排序(O(1)空间)
  • ✅ 适合小数据量

缺点

  • ❌ 时间复杂度高 O(n²)
  • ❌ 大数据量性能差
  • ❌ 比较和交换次数多
  • ❌ 实际应用较少

应用场景

  1. 教学演示:算法入门的经典案例
  2. 小数据集:数据量很小(<10个元素)
  3. 几乎有序:数据基本有序时,优化后性能可接受
  4. 稳定性要求:需要稳定排序且数据量小

何时使用冒泡排序

  • ✅ 数据量很小(通常 < 10)
  • ✅ 数据基本有序
  • ✅ 需要稳定排序
  • ✅ 代码简洁性比性能更重要
  • ❌ 不推荐:大数据量、性能敏感场景

相关主题


返回:排序算法 | 算法学习导航