思路
数组长度为 n,每一轮将一个最大的数放到最右边,最后剩一个数不用排,n-1 轮就能排好。第 i 轮需要排 n - i -1 次。
代码
public class BubbleSort{
public static void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
public static void main(String[] args){
int[] array = new int[]{5,8,6,3,9,2,1,4,7};
bubbleSort(array);
System.out.println(Arrays.toString(array));
}
}
优化1
到某一轮发现没有交换过,提前终止排序
public class BubbleSort{
public static void bubbleSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
boolean isSorted = true;
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
isSorted = false;
}
}
if (isSorted)
return;
}
}
public static void main (String[] args){
int[] array = new int[]{5,8,6,3,9,2,1,4,7};
bubbleSort(array);
System.out.println(Arrays.toString(array));
}
}
优化2
每一轮不一定要比较 n - i -1 次,如果发现后面是有序的,可以缩小每一轮比较的边界
public class BubbleSort{
public static void bubbleSort(int[] arr) {
int border = arr.length - 1;
int lastExchangeIndex = 0;
for (int i = 0; i < arr.length - 1; i++) {
boolean isSorted = true;
for (int j = 0; j < border; j++) {
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
isSorted = false;
lastExchangeIndex = j;
}
}
if (isSorted)
return;
border = lastExchangeIndex;
}
}
public static void main (String[] args){
int[] array = new int[]{5,8,6,3,9,2,1,4,7};
bubbleSort(array);
System.out.println(Arrays.toString(array));
}
}
复杂度分析
时间复杂度
双重循环,平均O(n2)
最坏逆序,O(n2)
最好顺序,比较一轮,一轮比较 n-1 次,O(n)
空间复杂度
额外空间与数组长度无关
O(1)
稳定性分析
挨着交换,稳定
优势
稳定,空间复杂度为 O(1)
适用场景
数据量小、部分有序(特别是改良后的)