冒泡排序练习案例,从基础应用到优化拓展,每个案例均包含解题思路、完整代码和输出结果:
案例1:基础难度 - 对整数数组进行升序排序
题目:使用冒泡排序对数组 [6, 2, 9, 1, 5]
进行升序排序,输出每一轮排序后的数组状态。
解题思路
- 明确冒泡排序核心:通过相邻元素比较,将大元素逐步“沉”到数组末尾。
- 外层循环控制排序轮次(数组长度为
n
,需n-1
轮)。 - 内层循环控制每轮比较次数(第
i
轮比较n-1-i
次,因已有i
个元素排好序)。 - 每轮比较相邻元素,若前>后则交换,完成后打印当前数组状态。
代码实现
import java.util.Arrays;
public class BubbleSortBasic {
public static void main(String[] args) {
int[] arr = {6, 2, 9, 1, 5};
int n = arr.length;
System.out.println("初始数组:" + Arrays.toString(arr));
System.out.println("-----排序过程-----");
// 外层循环:控制轮次(n-1轮)
for (int i = 0; i < n - 1; i++) {
// 内层循环:控制每轮比较次数(n-1-i次)
for (int j = 0; j < n - 1 - i; j++) {
// 比较相邻元素,前>后则交换
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
// 打印第i+1轮后的数组
System.out.println("第" + (i + 1) + "轮:" + Arrays.toString(arr));
}
System.out.println("-----排序结果-----");
System.out.println("升序数组:" + Arrays.toString(arr));
}
}
输出结果
初始数组:[6, 2, 9, 1, 5]
-----排序过程-----
第1轮:[2, 6, 1, 5, 9] // 最大元素9沉到末尾
第2轮:[2, 1, 5, 6, 9] // 次大元素6沉到倒数第2位
第3轮:[1, 2, 5, 6, 9] // 第三大元素5沉到倒数第3位
第4轮:[1, 2, 5, 6, 9] // 剩余元素已排序,无交换
-----排序结果-----
升序数组:[1, 2, 5, 6, 9]
案例2:中等难度 - 对字符串数组进行降序排序
题目:使用冒泡排序对字符串数组 ["apple", "banana", "cherry", "date"]
按字典序降序排序(即从后往前排,如"date" > "cherry" > "banana" > "apple"
)。
解题思路
- 字符串比较需使用
compareTo
方法:str1.compareTo(str2)
返回正数表示str1
在字典序中位置靠后。 - 降序排序的交换条件:若
str[j].compareTo(str[j+1]) < 0
(即str[j]
比str[j+1]
小),则交换位置。 - 其余逻辑与整数排序一致,外层控制轮次,内层控制比较次数。
代码实现
import java.util.Arrays;
public class BubbleSortString {
public static void main(String[] args) {
String[] fruits = {"apple", "banana", "cherry", "date"};
int n = fruits.length;
System.out.println("初始数组:" + Arrays.toString(fruits));
System.out.println("-----排序过程-----");
// 外层循环:n-1轮
for (int i = 0; i < n - 1; i++) {
// 内层循环:每轮比较n-1-i次
for (int j = 0; j < n - 1 - i; j++) {
// 字符串降序:若前 < 后,则交换
if (fruits[j].compareTo(fruits[j + 1]) < 0) {
String temp = fruits[j];
fruits[j] = fruits[j + 1];
fruits[j + 1] = temp;
}
}
System.out.println("第" + (i + 1) + "轮:" + Arrays.toString(fruits));
}
System.out.println("-----排序结果-----");
System.out.println("降序数组:" + Arrays.toString(fruits));
}
}
输出结果
初始数组:[apple, banana, cherry, date]
-----排序过程-----
第1轮:[banana, cherry, date, apple] // 最小的"apple"沉到末尾
第2轮:[cherry, date, banana, apple] // 次小的"banana"沉到倒数第2位
第3轮:[date, cherry, banana, apple] // 剩余元素排序完成
-----排序结果-----
降序数组:[date, cherry, banana, apple]
案例3:进阶难度 - 优化冒泡排序(减少无效遍历)
题目:对数组 [3, 1, 2, 4, 5]
使用优化后的冒泡排序(若某轮无交换则提前终止),输出排序过程及最终结果,观察优化效果。
解题思路
- 基础冒泡排序即使数组提前有序,仍会执行完所有轮次,存在无效遍历。
- 优化方案:添加
boolean
变量hasSwapped
标记本轮是否发生交换,若未交换则说明数组已有序,直接终止循环。 - 针对近乎有序的数组(如本题),优化后可大幅减少轮次。
代码实现
import java.util.Arrays;
public class OptimizedBubbleSort {
public static void main(String[] args) {
int[] nums = {3, 1, 2, 4, 5};
int n = nums.length;
boolean hasSwapped; // 标记本轮是否交换
System.out.println("初始数组:" + Arrays.toString(nums));
System.out.println("-----排序过程-----");
for (int i = 0; i < n - 1; i++) {
hasSwapped = false; // 每轮初始化未交换
for (int j = 0; j < n - 1 - i; j++) {
// 升序排序:前 > 后则交换
if (nums[j] > nums[j + 1]) {
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
hasSwapped = true; // 发生交换,标记为true
}
}
System.out.println("第" + (i + 1) + "轮:" + Arrays.toString(nums));
// 若本轮无交换,数组已有序,提前退出
if (!hasSwapped) {
System.out.println("数组已有序,提前终止排序");
break;
}
}
System.out.println("-----排序结果-----");
System.out.println("升序数组:" + Arrays.toString(nums));
}
}
输出结果
初始数组:[3, 1, 2, 4, 5]
-----排序过程-----
第1轮:[1, 2, 3, 4, 5] // 交换3和1、3和2,数组变为有序
第2轮:[1, 2, 3, 4, 5] // 本轮无任何交换
数组已有序,提前终止排序
-----排序结果-----
升序数组:[1, 2, 3, 4, 5]
优化效果:原需4轮的排序,因第2轮无交换,提前终止,减少了2轮无效遍历。
总结
- 案例1掌握整数升序排序的基础逻辑,核心是相邻比较与交换。
- 案例2拓展到字符串排序,理解
compareTo
方法在对象排序中的应用。 - 案例3通过优化减少无效遍历,理解冒泡排序的性能优化思路。
三个案例逐步深入,覆盖了冒泡排序的核心用法、拓展场景和优化技巧,适合从入门到熟练掌握。