冒泡排序(Bubble Sort)是一种简单的排序算法,它通过重复地遍历要排序的列表,依次比较相邻的两个元素,并根据需要交换它们的位置,从而使较大的元素逐渐“浮”到列表的末尾。这个过程类似于气泡在水中的上升,因此得名“冒泡排序”。
基本思想
- 初始状态:假设我们有一个无序的数组
arr
,其长度为n
。 - 外层循环:从第一个元素开始遍历到倒数第二个元素。每轮外层循环结束后,最大的元素会被放到正确的位置。
- 内层循环:在每次外层循环中,进行一次完整的内层循环。内层循环从数组的第一个元素开始遍历到当前外层循环的最后一个未排序元素。
- 比较和交换:在内层循环中,相邻的两个元素进行比较。如果前一个元素大于后一个元素,则交换它们的位置。
- 终止条件:当没有发生任何交换时,说明数组已经有序,可以提前结束排序过程。
优化
在一次完整的遍历中,如果没有任何元素交换发生,说明列表已经有序,可以提前结束排序过程。
时间复杂度
- 最好情况(列表已经有序):O(n)
- 最坏情况(列表逆序):O(n²)
- 平均情况:O(n²)
空间复杂度
冒泡排序是原地排序算法,空间复杂度为 O(1)。
C语言实现
#include <stdio.h>
// 冒泡排序函数
void bubbleSort(int arr[], int n) {
int i, j;
int swapped; // 用于优化,标记是否发生交换
for (i = 0; i < n - 1; i++) {
swapped = 0; // 每次遍历前初始化为0
// 内层循环进行相邻元素比较和交换
for (j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// 交换 arr[j] 和 arr[j+1]
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = 1; // 标记发生了交换
}
}
// 如果没有发生交换,说明列表已经有序,提前结束
if (swapped == 0) {
break;
}
}
}
// 打印数组函数
void printArray(int arr[], int size) {
int i;
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr) / sizeof(arr[0]);
printf("原始数组: \n");
printArray(arr, n);
bubbleSort(arr, n);
printf("排序后的数组: \n");
printArray(arr, n);
return 0;
}
代码解析
-
bubbleSort函数:
i
用于控制外层循环,表示已经排好序的元素个数。j
用于控制内层循环,负责遍历未排序的部分。swapped
是一个优化标志,用于判断在当前遍历中是否发生了交换。如果没有发生交换,说明数组已经有序,可以提前结束排序。
-
printArray函数:
- 用于打印数组中的元素。
-
main函数:
- 定义了一个待排序的数组
arr
,并计算数组的长度n
。 - 调用
bubbleSort
函数对数组进行排序,并打印排序前后的数组。
- 定义了一个待排序的数组
输出结果
原始数组:
64 34 25 12 22 11 90
排序后的数组:
11 12 22 25 34 64 90