原理:
思路:总共需要多少轮冒泡?需要n-1次。
冒泡:每一轮冒泡将会在剩下的(n-i)个元素中产生一个最大或者最少的值,
第一轮i等于0,第二轮i等于1…
而每一轮的冒泡需要比较(n-i-1)次即可确定一个极值,所以(n-i-1)就是一轮冒泡要比较的次数
所以具体第一轮参与冒泡的元素个数是与元素总量n有递减关系,并且参数冒泡的次数也是固定的为n-1,这种明显可量化的问题可以用一个很典型的二维嵌套循环来做控制。
实现:
public class BubbleSortTest {
public static void main(String[] args) {
int[] ints = {45, 67, 32, 90, 59, 12, 70};
int n = ints.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (ints[j] > ints[j + 1]) {
int temp = ints[j];
ints[j] = ints[j + 1];
ints[j + 1] = temp;
}
}
}
System.out.println(Arrays.toString(ints));
}
}
改进:
改进是为也提高冒泡排序的效率,可从两点出发:
1。减少每轮冒泡比较的元素个数,我们可以记下第一轮冒泡最后一次交换(j与j+1的交换)的下标j,而大于等于这个下标的元素都是已经排序好的。
如何证明是排序好的?反推法:如果不是排序好的,证明前面有元素比后面大,而这些元素都是经过冒泡的,如果有比后面大的就一定会冒泡到后面,那么最后一次交换下标为j是不成立的,因为这会比j大。
这个时候比较次数n-i-1可以用lastExchangeIndex代替
2。每一轮冒泡记下是否有元素交换,如果没有则可以证明所有的元素已经是有序的,这个时候直接终止外层循环
实现:
public class BubbleSortTest {
public static void main(String[] args) {
int[] ints = {45, 67, 32, 90, 59, 12, 70};
int n = ints.length;
int sortBoard = n - 1;
int lastExchangeIndex = 0;
for (int i = 0; i < n - 1; i++) {
boolean isSorted = true;
for (int j = 0; j < sortBoard; j++) {
if (ints[j] > ints[j + 1]) {
int temp = ints[j];
ints[j] = ints[j + 1];
ints[j + 1] = temp;
isSorted = false;
lastExchangeIndex = j;
}
}
if (isSorted) {
break;
}
sortBoard = lastExchangeIndex;
}
System.out.println(Arrays.toString(ints));
}
}