执行流程(升序)
从头开始相邻元素之间进行比较,如果第一个元素比第二个元素大,则进行交换位置 1.第一轮执行完,最后一个就是最大的元素 2.第二轮执行完,第二大的就是倒数第二大的元素 ......
代码
1.0.最简单最暴力
public static void bubbleSort(int[] array) {
int tmp = 0;
for (int end = array.length - 1; end > 0; end--) {
for (int start = 1; start <= end; start++) {
if (array[start] < array[start - 1]) {
tmp = array[start];
array[start] = array[start - 1];
array[start - 1] = tmp;
}
}
}
}
1.1.优化一
如果进过第一轮之后,如果发现没有一次交换,说明数组已经有序了,则不需要再进行下去了
public static void bubbleSort(int[] array) {
int tmp = 0;
//标记是否交换过
boolean isSwap = false;
for (int end = array.length - 1; end > 0; end--) {
for (int start = 1; start <= end; start++) {
if (array[start] < array[start - 1]) {
tmp = array[start];
array[start] = array[start - 1];
array[start - 1] = tmp;
//发生交换
isSwap = true;
}
}
//判断是否发生交换,如果没有交换,说明数组已经有序,提前退出
if (!isSwap) {
break;
}
}
}
1.2.优化二
如果数组结尾有部分元素已经有序,则尾部的这些有序的数组就不需要比较交换了
每一轮排序,记录下来最后一次交换元素的位置,比如上图,我们只要记录下1元素的坐标,下次只要比较到1元素的位置就行了,不需要在往下比较
public static void bubbleSort(int[] array) {
int tmp = 0;
for (int end = array.length - 1; end > 0; end--) {
//记录每一轮的最后一次交换位置
int index = 1;
for (int start = 1; start <= end; start++) {
if (array[start] < array[start - 1]) {
tmp = array[start];
array[start] = array[start - 1];
array[start - 1] = tmp;
//记录交换位置
index = start;
}
}
//下一轮只要比较到上一轮最后交换元素的位置
end = index;
}
}
复杂度分析
- 最坏/平均复杂度:O(n2)
- 最好时间复杂度:O(n)
- 空间复杂度:O(1)