冒泡排序(Bubble Sort)是一种简单且直观的排序算法。它通过重复地遍历待排序的数组,并在每次遍历过程中比较和交换相邻的元素,将较大的元素逐渐“冒泡”到数组的末尾,从而实现排序。冒泡排序的名字由此而来。
工作原理
- 初始状态:从数组的第一个元素开始,比较每一对相邻的元素,如果前一个元素大于后一个元素,就交换它们的位置。
- 第一轮遍历:经过第一轮遍历之后,最大的元素会被移动到数组的末尾。
- 重复步骤:对剩下的元素重复上述步骤,直到整个数组有序。
例子
假设我们有一个数组:[5, 3, 8, 4, 2]
-
第一轮遍历:
- 比较
5
和3
,交换,数组变为[3, 5, 8, 4, 2]
- 比较
5
和8
,不交换,数组保持[3, 5, 8, 4, 2]
- 比较
8
和4
,交换,数组变为[3, 5, 4, 8, 2]
- 比较
8
和2
,交换,数组变为[3, 5, 4, 2, 8]
- 最大的元素
8
被放置在正确的位置。
- 比较
-
第二轮遍历:
- 比较
3
和5
,不交换,数组保持[3, 5, 4, 2, 8]
- 比较
5
和4
,交换,数组变为[3, 4, 5, 2, 8]
- 比较
5
和2
,交换,数组变为[3, 4, 2, 5, 8]
- 次大的元素
5
被放置在正确的位置。
- 比较
-
第三轮遍历:
- 比较
3
和4
,不交换,数组保持[3, 4, 2, 5, 8]
- 比较
4
和2
,交换,数组变为[3, 2, 4, 5, 8]
- 第三大的元素
4
被放置在正确的位置。
- 比较
-
第四轮遍历:
- 比较
3
和2
,交换,数组变为[2, 3, 4, 5, 8]
- 数组已经完全有序。
- 比较
代码实现
以下是冒泡排序的 Java 实现:
public class BubbleSort {
public static void main(String[] args) {
int[] nums = {5, 3, 8, 4, 2};
// 冒泡排序
for (int i = 0; i < nums.length - 1; i++) {
for (int j = 0; j < nums.length - 1 - i; j++) {
if (nums[j] > nums[j + 1]) {
// 交换 nums[j] 和 nums[j + 1]
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
// 打印排序后的数组
for (int num : nums) {
System.out.println(num);
}
}
}
复杂度分析
-
时间复杂度:
- 最坏情况:
O(n^2)
,当数组是逆序时,需要进行n(n-1)/2
次比较和交换。 - 最好情况:
O(n)
,当数组已经有序时,只需要进行n-1
次比较,不需要任何交换。 - 平均情况:
O(n^2)
,无论数组初始状态如何,平均情况下仍需进行n(n-1)/2
次比较和交换。
- 最坏情况:
-
空间复杂度:
O(1)
,冒泡排序是原地排序算法,不需要额外的存储空间。
优化
冒泡排序可以进行一些优化,以减少不必要的比较和交换:
- 提前退出:如果在某次遍历中没有发生任何交换,说明数组已经有序,可以提前退出。
- 记录最后交换的位置:在每次遍历中记录最后一次交换的位置,下一次遍历只需要比较到这个位置即可。
以下是优化后的代码:
public class OptimizedBubbleSort {
public static void main(String[] args) {
int[] nums = {5, 3, 8, 4, 2};
// 冒泡排序(优化版)
boolean swapped;
for (int i = 0; i < nums.length - 1; i++) {
swapped = false;
for (int j = 0; j < nums.length - 1 - i; j++) {
if (nums[j] > nums[j + 1]) {
// 交换 nums[j] 和 nums[j + 1]
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
swapped = true;
}
}
// 如果没有发生交换,说明数组已经有序
if (!swapped) break;
}
// 打印排序后的数组
for (int num : nums) {
System.out.println(num);
}
}
}
总结
冒泡排序是一种简单易懂的排序算法,适用于小规模数据的排序任务。尽管其时间复杂度较高,但通过适当的优化可以在某些情况下提升性能。对于更大规模的数据排序任务,通常会选择更高效的排序算法,如快速排序、归并排序等。