冒泡排序是一种简单的排序算法,它重复地走访要排序的元素列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。这个过程持续重复,直到没有再需要交换,也就是数组已经按照要求排序完成。
让我们来详细讲解一下冒泡排序的步骤,以便小白能够听懂:
- 比较相邻元素: 首先,从数组的第一个元素开始,依次比较相邻的两个元素。
- 交换顺序: 如果第一个元素比第二个元素大(升序排序),则交换它们的位置;如果第一个元素比第二个元素小(降序排序),则不交换。
- 一轮比较完成后: 这样,一轮比较结束后,最大(或最小)的元素就“冒泡”到了数组的末尾。
- 减少比较范围: 下一轮比较时,数组的比较范围减少一个元素,因为最后一个元素已经是最大(或最小)的了,不需要再参与比较。
- 重复直到排序完成: 重复以上步骤,直到数组中的所有元素都排序完成。每次循环过程中,未排序部分的最大(或最小)元素会像气泡一样“冒泡”到最终的位置。
让我们通过一个简单的例子来说明冒泡排序的过程:
假设我们有一个数组 [5, 3, 8, 2, 7],我们希望按升序排序。
-
第一轮:
- 比较
5和3,交换位置,变为[3, 5, 8, 2, 7] - 比较
5和8,不交换位置,保持[3, 5, 8, 2, 7] - 比较
8和2,交换位置,变为[3, 5, 2, 8, 7] - 比较
8和7,交换位置,变为[3, 5, 2, 7, 8]
第一轮结束,最大的元素
8已经移动到最后。 - 比较
-
第二轮:
- 比较
3和5,不交换位置,保持[3, 5, 2, 7, 8] - 比较
5和2,交换位置,变为[3, 2, 5, 7, 8] - 比较
5和7,不交换位置,保持[3, 2, 5, 7, 8]
第二轮结束,第二大的元素
7移动到倒数第二位置。 - 比较
-
第三轮:
- 比较
3和2,交换位置,变为[2, 3, 5, 7, 8] - 比较
3和5,不交换位置,保持[2, 3, 5, 7, 8]
第三轮结束,第三大的元素
5移动到倒数第三位置。 - 比较
-
第四轮:
- 比较
2和3,不交换位置,保持[2, 3, 5, 7, 8]
第四轮结束,数组已经完全排序。
- 比较
因此,经过四轮排序,数组 [5, 3, 8, 2, 7] 按升序排序变为 [2, 3, 5, 7, 8]。
/**
* 交换排序-冒泡排序,O(n²),稳定
* 依次比较相邻2个元素,若后者比前者小则交换位置,使该轮对比结束后最大元素在末尾
* 重复上述过程,直到所有元素有序
*
* @param arr
*/
public static void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr, j, j + 1);
}
System.out.println(ArrayUtils.toString(arr));
}
}
}
冒泡排序的时间复杂度是 O(n^2),其中 n 是数组的长度,因为它需要进行多次遍历来完成排序操作。尽管冒泡排序简单直观,但对于大规模数据排序来说效率较低,通常在实际应用中不如快速排序、归并排序等更高效的排序算法。