冒泡排序:用Python实现从小到大排序

你有没有想过,水中的气泡是怎么上升的?它们会从水底慢慢往上冒,较大的气泡会更快到达水面。冒泡排序的名字就来源于这个现象——它会让数组中较大的元素“冒泡”到数组的末尾。

简单来说,冒泡排序(Bubble Sort)是一种基础的排序算法。它的核心思想是:重复地走访要排序的数组,一次比较两个相邻的元素,如果它们的顺序错误就交换位置,直到整个数组有序。

冒泡排序的工作步骤

  1. 比较相邻元素:从数组第一个元素开始,依次比较相邻的两个元素(比如第1个和第2个,第2个和第3个,…)。
  2. 交换元素:如果前一个元素比后一个大,就交换它们的位置。
  3. 重复操作:重复上述步骤,直到所有元素都“冒泡”到正确的位置。每完成一轮,数组末尾的一个最大元素就会被排好序。
  4. 优化提前终止:如果某一轮中没有发生任何交换,说明数组已经有序,无需继续排序。

用Python实现冒泡排序

下面通过一个具体例子理解排序过程,并写出Python代码。假设我们要排序数组:[64, 34, 25, 12, 22, 11, 90]

步骤分解(手动模拟):

  • 第1轮:比较相邻元素,最大的数(90)会“冒泡”到末尾,数组变为:[34, 25, 12, 22, 11, 64, 90]
  • 第2轮:比较前6个元素,第二大的数(64)会“冒泡”到倒数第二位,数组变为:[25, 12, 22, 11, 34, 64, 90]
  • 第3轮:继续比较,直到所有元素有序。

Python代码实现:

def bubble_sort(arr):
    n = len(arr)
    # 外层循环控制排序轮数(最多n-1轮)
    for i in range(n - 1):
        swapped = False  # 标记本轮是否发生交换
        # 内层循环比较相邻元素,每轮减少一次比较(末尾已排序)
        for j in range(0, n - i - 1):
            if arr[j] > arr[j + 1]:
                # 交换相邻元素(Python语法简化交换)
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
                swapped = True
        # 如果本轮无交换,说明数组已有序,提前终止
        if not swapped:
            break
        print(f"第{i+1}轮结束:{arr}")
    return arr

# 测试
test_arr = [64, 34, 25, 12, 22, 11, 90]
print("原始数组:", test_arr)
sorted_arr = bubble_sort(test_arr)
print("最终排序:", sorted_arr)

代码解释:

  1. 外层循环for i in range(n - 1)
    控制排序轮数,最多需要n-1轮(n为数组长度),因为每轮会确定一个最大元素的位置。

  2. 内层循环for j in range(0, n - i - 1)
    比较相邻元素,每轮内层循环的次数比上一轮少1次(因为末尾i个元素已排好序)。

  3. 交换逻辑arr[j], arr[j + 1] = arr[j + 1], arr[j]
    用Python的元组赋值语法,简洁交换相邻元素的值。

  4. 优化标志swapped
    如果某轮无交换,说明数组已有序,直接终止循环,避免无效比较。

运行结果(含中间过程):

原始数组: [64, 34, 25, 12, 22, 11, 90]
第1轮结束:[34, 25, 12, 22, 11, 64, 90]
第2轮结束:[25, 12, 22, 11, 34, 64, 90]
第3轮结束:[12, 22, 11, 25, 34, 64, 90]
第4轮结束:[12, 11, 22, 25, 34, 64, 90]
第5轮结束:[11, 12, 22, 25, 34, 64, 90]
最终排序: [11, 12, 22, 25, 34, 64, 90]

冒泡排序的特点

  • 时间复杂度:最坏情况(完全逆序)为O(n²),最好情况(已排序)为O(n)(优化后)。
  • 空间复杂度:O(1)(仅需临时变量,无额外空间)。
  • 稳定性:稳定排序(相等元素相对位置不变)。

总结

冒泡排序是最简单的排序算法之一,核心是“相邻元素比较与交换”。虽然效率较低(适合小规模数据),但理解其原理对掌握排序思想至关重要。通过Python代码实现后,你可以轻松处理简单的排序需求,或尝试优化为更高效的版本(如归并排序、快速排序)。

现在,尝试用其他数组(如[5, 3, 8, 4, 2])测试冒泡排序,看看是否能正确输出排序结果吧!

小夜