### 15. 综合示例
为了全面展示冒泡排序的各种实现和优化,我们可以编写一个综合示例,包含基本冒泡排序、优化版冒泡排序和鸡尾酒排序。
```java
public class ComprehensiveBubbleSort {
// 基本冒泡排序
public static void basicBubbleSort(int[] array) {
int n = array.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - 1 - i; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
// 优化版冒泡排序
public static void optimizedBubbleSort(int[] array) {
int n = array.length;
boolean swapped;
for (int i = 0; i < n - 1; i++) {
swapped = false;
for (int j = 0; j < n - 1 - i; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
swapped = true;
}
}
if (!swapped) break;
}
}
// 鸡尾酒排序
public static void cocktailShakerSort(int[] array) {
boolean swapped;
int start = 0;
int end = array.length;
do {
swapped = false;
for (int i = start; i < end - 1; i++) {
if (array[i] > array[i + 1]) {
int temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
swapped = true;
}
}
if (!swapped) break;
end--;
swapped = false;
for (int i = end - 1; i >= start; i--) {
if (array[i] > array[i + 1]) {
int temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
swapped = true;
}
}
start++;
} while (swapped);
}
public static void main(String[] args) {
int[] array = {5, 3, 8, 4, 2};
// 使用基本冒泡排序
basicBubbleSort(array.clone());
System.out.println("Basic Bubble Sort:");
printArray(array);
// 使用优化版冒泡排序
```java
int[] optimizedArray = {5, 3, 8, 4, 2};
optimizedBubbleSort(optimizedArray);
System.out.println("Optimized Bubble Sort:");
printArray(optimizedArray);
// 使用鸡尾酒排序
int[] cocktailArray = {5, 3, 8, 4, 2};
cocktailShakerSort(cocktailArray);
System.out.println("Cocktail Shaker Sort:");
printArray(cocktailArray);
}
// 打印数组
public static void printArray(int[] array) {
for (int i : array) {
System.out.print(i + " ");
}
System.out.println();
}
}
```
在这个综合示例中,我们定义了三个排序方法:基本冒泡排序、优化版冒泡排序和鸡尾酒排序。然后在`main`方法中分别调用这些排序方法,并打印排序后的数组。
### 16. 冒泡排序的详细步骤和解释
为了更好地理解冒泡排序,下面详细解释每一步的实现和优化方法:
#### 16.1 基本冒泡排序
基本冒泡排序通过两个嵌套的`for`循环实现:
- 外层循环`for (int i = 0; i < n - 1; i++)`控制遍历的次数。每次遍历后,最大的元素会被移动到数组的末尾,因此内层循环的范围逐渐减小。
- 内层循环`for (int j = 0; j < n - 1 - i; j++)`用于比较和交换相邻的元素。如果前一个元素大于后一个元素,则交换它们。
#### 16.2 优化版冒泡排序
优化版冒泡排序在基本冒泡排序的基础上增加了一个`swapped`标志:
- 每次内层循环开始前,将`swapped`设置为`false`。
- 如果发生了交换操作,则将`swapped`设置为`true`。
- 如果一次完整的内层循环后,`swapped`仍然为`false`,说明数组已经有序,可以提前终止排序过程。
#### 16.3 鸡尾酒排序
鸡尾酒排序是冒泡排序的双向版本,通过两个方向的遍历来提高排序效率:
- 定义`start`和`end`两个变量,分别表示未排序部分的起始和结束位置。
- 在每次遍历中,先从左到右进行冒泡排序,将最大的元素移动到末尾,然后从右到左进行冒泡排序,将最小的元素移动到开头。
- 每次遍历结束后,调整`start`和`end`的值,缩小未排序部分的范围。
### 17. 冒泡排序的代码优化和可读性提高
为了提高代码的可读性和可维护性,可以将常见操作封装为函数,并添加注释说明。
```java
public class EnhancedBubbleSort {
// 基本冒泡排序
public static void basicBubbleSort(int[] array) {
int n = array.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - 1 - i; j++) {
if (array[j] > array[j + 1]) {
swap(array, j, j + 1);
}
}
}
}
// 优化版冒泡排序
public static void optimizedBubbleSort(int[] array) {
int n = array.length;
boolean swapped;
for (int i = 0; i < n - 1; i++) {
swapped = false;
for (int j = 0; j < n - 1 - i; j++) {
if (array[j] > array[j + 1]) {
swap(array, j, j + 1);
swapped = true;
}
}
if (!swapped) break;
}
}
// 鸡尾酒排序
public static void cocktailShakerSort(int[] array) {
boolean swapped;
int start = 0;
int end = array.length;
do {
swapped = false;
for (int i = start; i < end - 1; i++) {
if (array[i] > array[i + 1]) {
swap(array, i, i + 1);
swapped = true;
}
}
if (!swapped) break;
end--;
swapped = false;
for (int i = end - 1; i >= start; i--) {
if (array[i] > array[i + 1]) {
swap(array, i, i + 1);
swapped = true;
}
}
start++;
} while (swapped);
}
// 交换数组中的两个元素
private static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static void main(String[] args) {
int[] array = {5, 3, 8, 4, 2};
// 使用基本冒泡排序
int[] basicArray = array.clone();
basicBubbleSort(basicArray);
System.out.println("Basic Bubble Sort:");
printArray(basicArray);
// 使用优化版冒泡排序
int[] optimizedArray = array.clone();
optimizedBubbleSort(optimizedArray);
System.out.println("Optimized Bubble Sort:");
printArray(optimizedArray);
// 使用鸡尾酒排序
int[] cocktailArray = array.clone();
cocktailShakerSort(cocktailArray);
System.out.println("Cocktail Shaker Sort:");
printArray(cocktailArray);
}
// 打印数组
public static void printArray(int[] array) {
for (int i : array) {
System.out.print(i + " ");
}
System.out.println();
}
}
```
在这个优化后的代码中,我们将交换元素的操作封装到`swap`方法中,减少代码重复,并通过注释提高代码的可读性。