冒泡排序法
冒泡排序完整讲解 + Java 两种写法(完整排序 / 只排 K 趟)
一、核心原理
1.遍历数组,相邻两个元素两两对比;
2.如果前一个 > 后一个,交换两者;
3.每完整遍历一趟,会把当前未排序区间最大的数 “冒泡” 到末尾;
4.有 n 个数字,最多需要 n-1 趟就能完全有序。
举个直观例子
数组:[3, 1, 4, 2]
第 1 趟:
3 和 1 交换 → [1,3,4,2]
3 和 4 不换
4 和 2 交换 → [1,3,2,4]
末尾 4 确定,不再参与后续比较。
第 2 趟:
1 和 3 不换
3 和 2 交换 → [1,2,3,4]
末尾 3、4 确定。
第 3 趟仅校验前两位,无交换,排序完成。
二、完整冒泡排序(把数组全部排好)
java
运行
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for(int i = 0; i < n; i++){
arr[i] = sc.nextInt();
}
sc.close();
// 外层:总共 n-1 趟
for(int i = 0; i < n - 1; i++){
// 内层:每趟少比较 i 个尾部有序数字
for(int j = 0; j < n - 1 - i; j++){
if(arr[j] > arr[j+1]){
// 交换
int t = arr[j];
arr[j] = arr[j+1];
arr[j+1] = t;
}
}
}
// 输出
for(int i = 0; i < n; i++){
if(i > 0) System.out.print(" ");
System.out.print(arr[i]);
}
}
}
三、题目专用:只执行 K 趟冒泡(中途输出结果)
java
运行
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int k = sc.nextInt();
int[] arr = new int[n];
for(int i = 0; i < n; i++){
arr[i] = sc.nextInt();
}
sc.close();
// 只执行 K 趟
for(int i = 0; i < k; i++){
for(int j = 0; j < n - 1 - i; j++){
if(arr[j] > arr[j+1]){
int t = arr[j];
arr[j] = arr[j+1];
arr[j+1] = t;
}
}
}
// 输出,末尾无空格
for(int i = 0; i < n; i++){
if(i != 0) System.out.print(" ");
System.out.print(arr[i]);
}
}
}
四、优化版冒泡(提前终止)
如果某一趟一次交换都没发生,说明数组已经有序,可以直接跳出循环,减少无用遍历:
java
运行
for(int i = 0; i < n - 1; i++){
boolean swap = false;
for(int j = 0; j < n - 1 - i; j++){
if(arr[j] > arr[j+1]){
int t = arr[j];
arr[j] = arr[j+1];
arr[j+1] = t;
swap = true;
}
}
if(!swap) break; // 无交换,提前结束
}
五、关键知识点总结
1.两层循环
·外层:控制第几趟;
·内层:控制每一趟相邻比较。
2.内层边界 j < n-1-i
前面 i 趟已经把 i 个最大值放到数组末尾,不用再比较。
3.从小到大排序:arr[j] > arr[j+1] 交换
从大到小排序:arr[j] < arr[j+1] 交换
4.时间复杂度
·最坏 / 平均:(O(n^2))
·优化后最好(已有序):(O(n))
5.稳定性:冒泡是稳定排序,相等数字不会交换位置,相对顺序不变。
浙公网安备 33010602011771号