【经典排序算法 time: 2023-10-12】冒泡排序(层层优化改进)

  1. 原理
    每次循环找出一个最大的元素(动态演示)
  2. 第一版冒泡
java 复制代码
public class Maopao1 {
    public static void main(String[] args) {
        long start= System.currentTimeMillis();
        int[] arr2 = {11, 23, 69, 99, 1, 3, 45, 67, 5, 234, 678, 999, 7, 123};
        int[] result = maopao(arr2);
        System.out.println(Arrays.toString(result));

        System.out.println(System.currentTimeMillis()-start);
    }

    private static int[] maopao(int[] arr2) {
        for (int i = 0; i < arr2.length - 1; i++) {
            for (int j = 0; j < arr2.length - 1; j++) {
                if (arr2[j] > arr2[j + 1]) {
                    swap(arr2, j, j + 1);
                }
            }
            System.out.println(Arrays.toString(arr2));
        }
        System.out.println("循环了" +( arr2.length-1) + "次");
        return arr2;
    }

    public static void swap(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
}
  1. 改进一:内层循环的次数与外层循环有关系,将a.length-1变成a.length-1-i,可以每次循环后减少一次循环次数。
java 复制代码
public class Maopao2 {
    public static void main(String[] args) {

        long start = System.currentTimeMillis();
        int[] arr2 = {11, 23, 69, 99, 1, 3, 45, 67, 5, 234, 678, 999, 7, 123};
        int[] result = maopao(arr2);
        System.out.println(Arrays.toString(result));
        System.out.println(System.currentTimeMillis()-start);
    }

    private static int[] maopao(int[] arr2) {
        for (int i = 0; i < arr2.length - 1; i++) {
            for (int j = 0; j < arr2.length - 1 - i; j++) {
                if (arr2[j] > arr2[j + 1]) {
                    swap(arr2, j, j + 1);
                }
            }
            System.out.println(Arrays.toString(arr2));
        }
        return arr2;
    }

    public static void swap(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
}
  1. 改进二,只要一轮比较没有发生交换,则可以提前结束冒泡,在本身有序的序列情况下,循环一次就行了
java 复制代码
public class Maopao2 {
    public static void main(String[] args) {

        long start = System.currentTimeMillis();
        int[] arr2 = {11, 23, 69, 99, 1, 3, 45, 67, 5, 234, 678, 999, 7, 123};
        int[] result = maopao(arr2);
        System.out.println(Arrays.toString(result));
        System.out.println(System.currentTimeMillis()-start);
    }

    private static int[] maopao(int[] arr2) {
        for (int i = 0; i < arr2.length - 1; i++) {
            boolean swapBool = false; // 发生交换
            for (int j = 0; j < arr2.length - 1 - i; j++) {
                if (arr2[j] > arr2[j + 1]) {
                    swap(arr2, j, j + 1);
                    swapBool = true;
                }
            }
            if (!swapBool) {
                System.out.println("循环了" + i + "次");
                break;
            }
            System.out.println(Arrays.toString(arr2));
        }
        return arr2;
    }

    public static void swap(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
}
  1. 改进三,只需要内层循环,外层使用while(ture),用内层最后一个交换的索引来退出循环,如果最后交换的索引等于0的话说明没有交换,推出循环;
java 复制代码
public class Maopao3 {
    public static void main(String[] args) {

        long start = System.currentTimeMillis();
        int[] arr2 = {11, 23, 69, 99, 1, 3, 45, 67, 5, 234, 678, 7, 123,999};
        int[] result = maopao(arr2);
        System.out.println(Arrays.toString(result));

        System.out.println(System.currentTimeMillis()-start);
    }

    private static int[] maopao(int[] arr2) {
        int n = arr2.length - 1;
        int num = 0;
        while (true) {
            int last = 0; // 最后一次交换的索引
            for (int j = 0; j < n; j++) {
                if (arr2[j] > arr2[j + 1]) {
                    swap(arr2, j, j + 1);
                    last = j;
                }
            }
            n = last;
            num++;
            if (n == 0) {
                break;
            }
            System.out.println(Arrays.toString(arr2));
        }
        System.out.println("循环了" + num + "次");
        return arr2;
    }

    public static void swap(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
}
相关推荐
Coder-magician19 分钟前
《代码随想录》刷题打卡day51:图论-part09(dijistra堆优化,Bellman_ford算法)
算法·图论
Nil20827 分钟前
leetcode 763划分字母区间
算法·leetcode·职场和发展
不会就选b37 分钟前
算法日常・每日刷题--<动态规划>20
算法·leetcode·动态规划
别动我齐刘海1 小时前
C++ 工程化学习
java·linux·前端·c++·学习·机器学习·机器人
青少儿编程课堂2 小时前
迪杰斯特拉(Dijkstra)算法:单源最短路与赛场路线规划
c++·python·算法·bfs·信息学竞赛
不会就选b2 小时前
算法日常・每日刷题--<动态规划>19
算法·leetcode·职场和发展
code2cat2 小时前
Java进阶篇之AtomicLongFieldUpdater:把累计额度留在对象字段中
java·cas·并发编程
WeiXin_DZbishe2 小时前
基于springboot城市公交实时运营与调度系统-计算机毕设 附源码【课程设计】66173
java·vue.js·spring boot·后端·python·php·课程设计
泡茶喝茶写代码2 小时前
A股量化数据工程:从 REST 接口到策略信号(第 18 篇):放量缩量异动扫描
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口