冒泡排序是一种较简单的排序算法。它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
基本思想
- 比较相邻的元素,如果第一个比第二个大,就交换它们两个
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数
- 针对所有的元素重复以上的步骤,除了最后一个
- 重复步骤1~3,直到排序完成
动态图如下(来源:https://www.cnblogs.com/onepixel/articles/7674659.html):

代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import java.util.Arrays; import java.util.Comparator;
public class BubbleSort {
private BubbleSort() {}
private static <T> void sort(T[] data, Comparator<T> comparator) { for (int i = 0; i < data.length - 1; i++) { for (int j = 0; j < data.length - 1 - i; j++) { if (comparator.compare(data[j], data[j + 1]) > 0) { swap(data, j, j + 1); } } } }
private static <T> void swap(T[] data, int i, int j) { T temp = data[i]; data[i] = data[j]; data[j] = temp; }
public static void main(String[] args) { Integer[] data = {3, 1, 2, 5, 4}; sort(data, Integer::compareTo); System.out.println(Arrays.toString(data)); } }
|
上述的冒泡排序是常规版的写法,其实我们还可以对冒泡排序进行优化。
- 优化一:当数组整体已经是有顺序的时候,例如:[1, 2, 3, 4, 5],此时我们已经不需要再进行后续的比较了。所以我们可以设置一个标志位,当数组没有发生交换元素时,我们给标志位设置为true并且可以退出循环了。
- 优化二:在冒泡排序中还有一个问题存在,数组前半部分无序,后半部分有序。例如:[2, 1,3, 4, 5],我们可以记下最后一次交换的位置,后边没有交换,必然是有序的,然后下一次排序从第一个比较到上次记录的位置结束即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
public class BubbleSort {
private BubbleSort() {}
private static <T> void sort(T[] data, Comparator<T> comparator) { int sortBorder = data.length - 1; int lastIndex = 0; for (int i = 0; i < data.length - 1; i++) { boolean isSort = true; for (int j = 0; j < sortBorder; j++) { if (comparator.compare(data[j], data[j + 1]) > 0) { swap(data, j, j + 1); isSort = false; lastIndex = j; } } sortBorder = lastIndex; if (isSort) { break; } } }
private static <T> void swap(T[] data, int i, int j) { T temp = data[i]; data[i] = data[j]; data[j] = temp; }
public static void main(String[] args) { Integer[] data = {3, 1, 2, 5, 4}; sort(data, Integer::compareTo); System.out.println(Arrays.toString(data)); } }
|