Java 冒泡排序

什么是冒泡排序?

一种简单直观的排序算法,它重复地走访过要排序的元素列,依次比较相邻的两个元素,如果顺序错误则交换它们,直到没有再需要交换的元素,排序完成。

冒泡排序的步骤:

  1. 比较相邻元素

    首先,比较数组中相邻的两个元素,依次向后移动。
  2. 交换元素位置

    如果发现前一个元素比后一个元素大,就交换它们的位置。
  3. 重复步骤

    重复步骤 1 和步骤 2,直到没有再需要交换的元素。这意味着数组已经按照升序排列完成。

代码案例:

public class BubbleSort {
    public static void bubbleSort(int[] arr) {
        int n = arr.length;
        // 外层循环控制排序轮数,最多进行 n-1 轮
        for (int i = 0; i < n - 1; i++) {
            // 内层循环控制每轮比较次数
            for (int j = 0; j < n - 1 - i; j++) {
                // 如果前面的元素大于后面的元素,交换它们
                if (arr[j] > arr[j + 1]) {
                    // 交换 arr[j] 和 arr[j + 1]
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }
​
    public static void main(String[] args) {
        // 测试用例
        int[] arr = {64, 34, 25, 12, 22, 11, 90};
        
        System.out.println("原始数组:");
        printArray(arr); // 打印原始数组
        
        // 调用冒泡排序算法
        bubbleSort(arr);
        
        System.out.println("排序后的数组:");
        printArray(arr); // 打印排序后的数组
    }
    
    // 打印数组的方法
    public static void printArray(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println(); // 换行
    }
}

详细步骤解释:

初始化数组

main 方法中,首先定义了一个整数数组 arr,包含了一些无序的整数。

打印原始数组

调用 printArray 方法,将原始数组打印出来,展示出未排序的状态。

调用冒泡排序算法

bubbleSort(arr) 方法被调用,开始对数组 arr 进行冒泡排序。

冒泡排序核心

  • 外层循环 for (int i = 0; i < n - 1; i++) 控制排序的轮数,其中 n 是数组长度。每轮排序会将当前未排序部分的最大元素冒泡到正确的位置。

  • 内层循环 for (int j = 0; j < n - 1 - i; j++) 对当前未排序部分的相邻元素进行比较和可能的交换,确保每轮结束后最大的元素位于正确的位置。

交换操作

如果发现 arr[j] > arr[j + 1],就交换 arr[j]arr[j + 1] 的值,保证较大的值“冒泡”到数组的右侧。

打印排序后的数组

冒泡排序完成后,再次调用 printArray 方法打印已排序的数组,展示出升序排列的结果。

优化冒泡排序

public static void bubbleSort(int[] arr) {
    int n = arr.length;
    boolean flag = false;    // 结束冒泡的条件
    // 外层循环控制排序轮数,最多进行 n-1 轮
    for (int i = 0; i < n - 1; i++) {
        // 内层循环控制每轮比较次数
        for (int j = 0; j < n - 1 - i; j++) {
            // 如果前面的元素大于后面的元素,交换它们
            if (arr[j] > arr[j + 1]) {
                // 交换 arr[j] 和 arr[j + 1]
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                flag = true;    // 如果执行了交换,则修改flag值
            }
        }
​
        // 判断flag变量有没有变动
        // 如果没有变动,表示这一轮循环都没有进入交换操作,说明数组已经有序,可以提前结束排序过程
        if (!flag) {
            break;
        } else {
            // 每次内层循环完毕修改flag的值
            flag = false;
        }
    }
}

代码解释:

初始化变量​​​​

  • int n = arr.length; 获取数组的长度,确定要排序的元素个数。

  • boolean flag = false; 这个标志变量用来指示是否进行了交换操作。初始为 false,表示本轮排序开始时还没有进行交换。

外层循环

  • for (int i = 0; i < n - 1; i++) 控制排序的轮数,最多进行 n-1 轮。每完成一轮,最大的元素就会被冒泡到正确的位置。

内层循环

  • for (int j = 0; j < n - 1 - i; j++) 在每一轮中,对相邻的元素进行比较和可能的交换操作。

交换操作和标志变量的使用

  • if (arr[j] > arr[j + 1]) 如果前面的元素比后面的元素大,则执行交换,并将 flag 设置为 true 表示进行了交换操作。

  • 如果在一轮内部循环中没有进行任何交换操作(即 flag 仍为 false),则说明数组已经有序,可以提前结束排序过程,以节省不必要的比较。

优化效果

  • 这种优化可以显著减少冒泡排序的比较次数,特别是对于近乎有序的数组或者数据集,可以大幅度提升算法的效率。

维护标志变量

  • 每次内层循环完成后,不管是否进行了交换,都会将 flag 重新设置为 false,以便下一轮内层循环开始时重新判断是否有交换操作。

总结:

这段代码在经典的冒泡排序基础上增加了一个 flag 变量,通过检测是否进行了交换来判断是否可以提前结束排序。这种优化对于某些特定情况下的数组可以显著提升性能,使得排序算法更加高效。

欧了,到这里我应该解释的差不多啦,我是南极,勇敢做自己,活出精彩的人生

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值