阅读 52

用最土的方式把细节剖给你看——冒泡排序算法的 Java 实现版

说到算法,很多人都会害怕。但是想升职加薪怎么办呢?

总是逃避是改变不了什么,也解决不了什么问题。我不希望自己以后一直被这些算法堵住,但同时也不强求一下子掌握优雅的实现算法。

一点一点地吃透它。

冒泡排序的概念:

不断的比较相邻的元素,如果顺序不对,就交换。 一轮又一轮,直到所有相邻的元素都比较完,是一种非常朴素的排序方法。

摆平心态放大招

 import java.util.Arrays; public class 冒泡算法 {     // 优化点:挨个比较了一圈,没有交换,说明已经排好了;已经有序的不要去交换了     public static void main(String[] args) {         int[] values = {3, 1, 6, 2, 9, 0, 7, 4, 5, 8};         bubbleSort(values);         System.out.println(Arrays.toString(values));     }     private static void bubbleSort(int[] values) {         int temp;         for (int i=0; i<values.length; i++) {             for (int j = 0; j<values.length-1-i; j++) {                  if (values[j] > values[j+1]) {  // 这一行决定了是从小到大,还是从大到小                     temp = values[j];                     values[j] = values[j+1];                     values[j+1] = temp;                 }                 System.out.println(i + ": " + Arrays.toString(values));             }             System.out.println();         }     } } 复制代码

我手敲了基础实现版后,还加了很多 print,把过程复现,然后理解程序的每一句话实现了什么,改变了什么,就会更容易理解一些。

  1. 核心实现部分,嵌套循环,挨个比较:

image.png 这一行可以看到 values[j]values[j+1] 分别是前一个元素和后一个元素。我文章里用的是前一个大于后一个的话,就交换,也就是把前一个元素往后堆,循环这个过程,就很像泡泡。一个一个这样冒到最后。

最后的排序结果:

image.png

  1. 这里 j 的上界没有取 values.length, 就是因为每次冒过去,最大值已经排到最后了。

image.png

  1. 我们来仔细看看,每个循环内做了什么样的事情:

  • 第一个循环:

image.png 第一个循环,一共 0-9,10个元素,两两比较,比较 9 次。

  • 第二个循环,最后两个肯定比较好了,少一次比较:

image.png

  • 第三个循环:

image.png

  • 第四个循环:

image.png

  • 第五 ~ 第九个循环:

image.png

也就是这个时候,你是不是明白了,为什么那么多调优文章都说,有重复的了吧?

到这里看起来已经非常棒了,上面我们已经对冒泡的次数,以及每次冒泡需要比较的次数都做了优化,但这就够了嘛,不 我们还可以对比较的次数做进一步的优化,每轮冒泡时,最后一次交换的索引可以作为下一轮冒泡比较的次数,如果这个值是 0, 就证明整个数组有序,直接退出外层循环即可。「非正经程序员 juejin.cn/post/701632… 」

优化了!

上面的截图已经很清楚地表现了代码可以优化的地方:

让这个循环在有序的情况下别比较了。

private static void bubbleSort(int[] values) {     int temp;     for (int i=0; i<values.length; i++) {         boolean flag = true;         for (int j = 0; j<values.length-1-i; j++) {             if (values[j] > values[j+1]) {                 temp = values[j];                 values[j] = values[j+1];                 values[j+1] = temp;                 // 发生交换了,就改变,数组在这一趟是无序的,还要接着比较                 flag = false;             }             System.out.println(i + ": " + Arrays.toString(values));         }         // 内循环都跑完了,flag 还是 true,说明已经有序了,后面不用再比较了         if (flag) {             break;         }         System.out.println();     } } 复制代码

我们是通过新增了一个布尔变量实现的: image.png

重新跑一次以后发现,前面的循环和之前都一样,不同的是排好序以后,就不再进行多余的比较了:

image.png


作者:小小匚
链接:https://juejin.cn/post/7018198518343041061


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐