一、冒泡排序的基本思想
基本思想:在一个无序数组中,从下标为0的元素开始,依次通过比对相邻元素的大小,把每一对相邻元素中较小的元素”浮“到前面,较大的元素”沉“到后面。就像鱼儿在水底吐出的泡泡逐渐往水面上浮变大的过程。
二、算法步骤
- 从第一个元素开始,比较相邻的元素。如果第一个比第二个大,就交换他们的位置。
- 对之后每一对相邻元素作同样的比较,从开始第一对到结尾的最后一对。此时最后一位元素是最大的数。
- 对后续所有的元素重复以上步骤,除去最后一个(每趟会将其最大元素放到最后位置)。
- 继续对后续越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
以[ 2, 8, -3, 10, -1 ]这组数为例,对这组数使用冒泡排序使其有序:
第一轮排序:
第二轮排序:
因为10的位置已经固定,所以只对前4个进行排序即可:
第二轮结束,将第二大的元素放到了倒数第二个位置。
第三轮排序:
8和10的位置已经确定,只需对前三个进行排序
第三轮过后,将第三大的元素位置确定
第四轮排序:
只需对前两个元素进行排序了
第四轮过后,第四大的元素位置已确定,总共5个元素,已经排序好4个,最后一个就是排好序的了
三、冒泡排序的Java代码实现
public class BubbleSort {
//冒泡排序方法
public static int[] bubbleSort(int[] nums) {
int n = nums.length;
for (int i = 0; i < n - 1; i++) {//外层循环代表排序趟数,注意是n-1趟足以保证有序
for (int j = 0; j < n - 1 - i; j++) {//内层循环代表每趟比较多少次
//如果当前元素大于后一位元素,则进行交换
if (nums[j] > nums[j + 1]) {
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
return nums;
}
public static void main(String[] args) {
System.out.println(Arrays.toString(bubbleSort(new int[]{2, 8, -3, 10, -1})));
}
}
四、冒泡排序的优化
优化的目的:数组可能在中间某一趟就已经整体有序,无序再进行后面操作。
标记交换:用一个临时变量作为标记,如果在一趟遍历中没有发生任何交换,则说明数组已经有序,此时可以提前结束排序。
public class BubbleSort {
//冒泡排序方法
public static int[] bubbleSort(int[] nums) {
boolean flag = false;//临时变量
int n = nums.length;
for (int i = 0; i < n - 1; i++) {//外层循环代表排序趟数,注意是n-1趟足以保证有序
for (int j = 0; j < n - 1 - i; j++) {//内层循环代表每趟比较多少次
//如果当前元素大于后一位元素,则进行交换
if (nums[j] > nums[j + 1]) {
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
flag = true;
}
}
//如果没有交换则证明数组已经有序,直接退出循环即可
if (!flag) {
break;
}
}
return nums;
}
public static void main(String[] args) {
System.out.println(Arrays.toString(bubbleSort(new int[]{2, 8, -3, 10, -1})));
}
}
五、冒泡排序的时间复杂度和空间复杂度
- 时间复杂度:
- 最好情况:数组已经有序,此时只需遍历一次,时间复杂度为O(n)。
- 最坏情况:数组完全倒序,此时需要遍历n-1次,每次遍历都要进行n-i次比较和可能的交换(i为当前遍历的次数),因此时间复杂度为O(n^2)。
- 平均情况:时间复杂度为O(n^2)。
- 空间复杂度:
- 冒泡排序只需要一个额外的空间来存储临时变量,因此空间复杂度为O(1)。
六、冒泡排序的适用场景
- 小数据集排序。对于较小的数据集,冒泡排序的性能是可以接受的,而且实现简单,易于理解和实现,因此经常被用作教学示例。
- 稳定性要求高的场景。冒泡排序是一种稳定的排序算法,即相等元素的相对顺序在排序后保持不变。
- 嵌入式系统或低级编程。在资源受限的嵌入式系统或低级编程环境中,冒泡排序的简单性可能使其成为首选算法,因为它不需要额外的数据结构或复杂的操作。
七、冒泡排序的优缺点
优点:
- 简单易懂:冒泡排序算法逻辑简单,易于理解和实现。
- 稳定性:冒泡排序是一种稳定的排序算法,即相等的元素在排序后保持原有的相对顺序。
- 空间效率高:冒泡排序只需一个额外空间来存储临时变量,空间复杂度非常低,为O(1)。
缺点:
- 时间效率低:冒泡排序的时间复杂度较高,平均时间复杂度和最坏时间复杂度都为O(n^2),其中n为待排序数据元素的个数。
- 不适合大数据集:由于冒泡排序的时间效率问题,它不适合用于排序大数据集。对于大数据集,应该选择更高效的排序算法,如归并排序、快速排序或堆排序等。
总结
综上所述,冒泡排序是一种简单易懂的排序算法,通过相邻元素之间的比较和交换来实现排序。虽然它效率上不如其他排序算法,但在某些特定场景下仍然有其应用价值。