我们要把相邻的元素两两比较,当一个元素大于右侧元素,交换元素位置,当小于等于右侧元素,位置保持不变,这是冒泡排序的的核心思想
- 使用双重循环进行排序,外部的循环控制所有回合,内部循环交换元素。
/**
* 冒泡排序 1
* 使用双重循环排序
* 外部循环控制所有回合
* 内部循环实现每一轮的冒泡处理 先进行元素比较再交换
*/
@Test
void bubbleSort1() {
int[] array = new int[]{5, 6, 4, 2, 3, 1, 9, 8, 7};
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length - i - 1; j++) {
int temp;
if (array[j] > array[j + 1]) {
//交换元素
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
System.out.println(Arrays.toString(array));
}
- 利用布尔变量isSorted作为标记,如果没有交换元素,元素已经有序,就没有交换的必要了
/**
* 优化 1
* 如果元素已经有序,就没有交换的必要了
*/
@Test
void bubbleSort2() {
int[] array = new int[]{2, 1, 5, 6, 7, 8, 9, 10};
for (int i = 0; i < array.length; i++) {
// 有序标记 每一轮都是true
boolean isSorted = true;
for (int j = 0; j < array.length - i - 1; j++) {
int temp;
if (array[j] > array[j + 1]) {
//交换元素
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
// 交换了元素 所以还需要继续
isSorted = false;
}
}
if (isSorted) {
break;
}
}
System.out.println(Arrays.toString(array));
}
- 记录最后一次交换位置,每次只比较到标记下标, sortSide之后的元素就不比较了,肯定是有序的
/**
* 优化 2
* 记录最后一次交换位置,每次只比较到标记下标
* sortSide之后的元素就不比较了
*/
@Test
void bubbleSort3() {
int[] array = new int[]{2, 1, 5, 6, 7, 8, 9, 10};
// 记录最后一次交换的位置
int lastExchangeIndex = 0;
// 无序数组的边界,每次比较到这里即可
int sortSide = array.length - 1;
for (int i = 0; i < array.length; i++) {
// 有序标记 每一轮都是true
boolean isSorted = true;
for (int j = 0; j < sortSide; j++) {
int temp;
if (array[j] > array[j + 1]) {
//交换元素
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
// 交换了元素 所以还需要继续
isSorted = false;
// 更新最后一次交换元素的位置标
lastExchangeIndex = j;
}
}
sortSide = lastExchangeIndex;
if (isSorted) {
break;
}
}
System.out.println(Arrays.toString(array));
}
- 如果大部分元素有序的情况下,鸡尾酒排序更能减少循环次数,它的过程就像摆钟一样,比较和交换的过程是双向的
/**
* 鸡尾酒排序的元素比较和交换过程是双向的
*/
@Test
void cocktailSort3() {
int[] array = new int[]{2, 1, 5, 6, 7, 8, 9, 10};
int temp;
for (int i = 0; i < array.length / 2; i++) {
// 有序标记 每一轮都是true
boolean isSorted = true;
// 奇数轮 ,从左向右交换比较
for (int j = i; j < array.length - i - 1; j++) {
if (array[j] > array[j + 1]) {
//交换元素
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
// 交换了元素 所以还需要继续
isSorted = false;
}
}
if (isSorted) {
break;
}
isSorted = true;
// 偶数轮 ,从右向左交换比较
for (int j = array.length - i - 1; j > i; j--) {
if (array[j] < array[j - 1]) {
//交换元素
temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
// 交换了元素 所以还需要继续
isSorted = false;
}
}
if (isSorted) {
break;
}
}
System.out.println(Arrays.toString(array));
}