import java.util.Arrays;

/**
 * @author WanJl
 * @version 1.0
 * @title Demo04
 * @description 数组排序-冒泡排序
 * @create 2026/7/16
 */
public class Demo04 {
    /*
        我们现在已经学了最基础的  数据结构与算法
        数据结构：数组结构--属于线性结构的一种
        算法：比如排序算法（冒泡、选择、插入...）
        冒泡排序，是所有排序【算法】最直观的，最基础的一种。
        冒泡排序就像水里的泡泡一样，大的元素会逐渐的冒到数组的末端。

        冒泡排序的核心思想：
            重复遍历数组，依次比较相邻的两个元素，如果顺序错误（假如是从小到大排序，但a比b大）就交换。
            每轮遍历把当前未排序的部分的最大值“冒泡”到正确位置。
     */
    public static void main(String[] args) {
        /*
            冒泡排序的基础版
            每一轮把未排序部分的最大值“冒泡”到数组末尾
         */
        int[] arr={1,456,782,5,8,4,598,1,46,68,465,74};
        //冒泡排序需要两层循环
        for (int i = 0; i <arr.length-1; i++) {  //外层循环，控制的一共冒泡多少轮
            //内层循环 在未排序的区间[0,arr.length-1-i] 中相邻比较
            //因为 i 后面的元素已经有序了，不需要再比较了
            for (int j = 0; j < arr.length-1-i; j++) {
                if (arr[j]>arr[j+1]){
                    //交换位置
                    arr[j]=arr[j]+arr[j+1];
                    arr[j+1]=arr[j]-arr[j+1];
                    arr[j]=arr[j]-arr[j+1];
                }
            }
        }
        System.out.println(Arrays.toString(arr));

        // 优化版
        int[] arr2={1,456,782,5,8,4,598,1,46,68,465,74};
        //冒泡排序需要两层循环
        for (int i = 0; i <arr2.length-1; i++) {  //外层循环，控制的一共冒泡多少轮
            boolean b=false;    //定义boolean类型的变量，用来标记本轮是否有交换
            //内层循环 在未排序的区间[0,arr.length-1-i] 中相邻比较
            //因为 i 后面的元素已经有序了，不需要再比较了
            for (int j = 0; j < arr2.length-1-i; j++) {
                if (arr2[j]>arr2[j+1]){
                    //交换位置
                    arr2[j]=arr2[j]+arr2[j+1];
                    arr2[j+1]=arr2[j]-arr2[j+1];
                    arr2[j]=arr2[j]-arr2[j+1];
                    b=true; //本轮有交换
                }
            }
            //判断，如果本轮没有发生任何交换，说明数组已经有序，提前结束
            if (b==false){
                break;
            }
            System.out.println("第"+(i+1)+"轮冒泡后："+Arrays.toString(arr2));
        }

    }
}
