排序算法图解之Java冒泡排序及优化

作者:兴趣使然黄小黄 时间:2022-07-16 01:28:38 

1.冒泡排序简介

冒泡排序(Bubble Sorting)即:通过对待排序的序列从前往后,依次比较相邻元素的值,若发现逆序则交换位置,使较大的元素逐渐移动到后部,就像水底的气泡一样逐渐从水面冒出来,这就是冒泡名称的由来

2.图解算法

以将序列{3, 9, -1, 10, -20}从小到大排序为例!

基本思想就是,在每一趟排序实现将最大的数移到序列的最后端!这主要通过比较相邻两个元素实现,当相邻的两个元素逆序的时候,我们就交换它们。

第1趟排序:

第1趟排序共比较了4次,将最大的数10冒泡到了序列的尾部。

排序算法图解之Java冒泡排序及优化

第2趟排序:

由于第一趟排序已经将最大是数10给冒泡到了最末端,因此在本次排序中,不需要再比较最后一个元素,故共比较了3次,将子序列(前四个元素)中最大的数9(整个序列中倒数第二大的数)冒泡到了子序列的尾端(原序列的倒数第二个位置)。

排序算法图解之Java冒泡排序及优化

第3趟排序:

在第三趟排序时,同理,倒数两个元素位置已经确定,即第一、第二大的数已经排好位置,只需要再将倒数第三大的数确认即可。故比较2次,实现倒数第三大的数3的位置确定。

排序算法图解之Java冒泡排序及优化

第4趟排序:

在第四趟排序时,只有第一、第二个元素的位置还不确定,只需要比较一次,若逆序,则交换即可。到此,排序算法完成,原序列已经排序成为一个递增的序列!

排序算法图解之Java冒泡排序及优化

小结

一共进行了数组大小-1次趟排序,即外层循环arr.length-1次;每趟排序进行了逐趟减小次数的比较,即内层循环arr.length-i-1次,i从0依次增加。

3.冒泡排序代码实现

参考代码如下,为了便于观察结果,在循环中添加了相应的输出语句:

import java.util.Arrays;

/**
* @author 兴趣使然黄小黄
* @version 1.0
* 冒泡排序
*/
public class BubbleSort {

public static void main(String[] args) {
       int[] array = {3, 9, -1, 10, -20};
       //排序前
       System.out.println("排序前:" + Arrays.toString(array));

//冒泡排序
       for (int i = 0; i < array.length - 1; i++) {
           System.out.println("第" + (i+1) + "趟排序开始!");
           for (int j = 0; j < array.length - i - 1; j++) {
               //如果前面的数比后面的数大,则交换
               if(array[j] > array[j+1]){
                   //交换
                   int temp = array[j];
                   array[j] = array[j+1];
                   array[j+1] = temp;
               }
               System.out.println("------第" + (j+1) + "趟排序: " + Arrays.toString(array));
           }
           System.out.println("第" + (i+1) + "趟排序完成: " + Arrays.toString(array));
           System.out.println("================================================");
       }

//输出排序后的结果
       System.out.println("排序后:" + Arrays.toString(array));
   }
}

实现结果:

排序算法图解之Java冒泡排序及优化

4.冒泡排序算法的优化

举个例子,将待排序的序列改为:{5,1,2,3,4},用以上算法来处理,观察一下结果:

排序算法图解之Java冒泡排序及优化

可以发现,当第一趟排序结束的时候,序列已经排序完成: 即将5冒泡到了最后,序列实现了从小到大排序。但是原冒泡排序算法,还是义无反顾的进行了数组大小-1趟排序(我可真是大冤种!)

因此,我们需要尝试对算法进行优化!

发现:在冒泡排序的过程中,各个元素都在不断的接近自己的位置,如果下一趟比较中没有进行过任何交换,则说明序列已经有序, 则排序算法已经可以返回结果。因此,考虑在排序算法过程中添加一个标志flag判断元素是否进行过交换,以减少不必要的冤种行为!

优化代码如下:

import java.util.Arrays;

/**
* @author 兴趣使然黄小黄
* @version 1.0
* 冒泡排序优化
*/
public class BubbleSort {

public static void main(String[] args) {
       int[] array = {5, 1, 2, 3, 4};
       //排序前
       System.out.println("排序前:" + Arrays.toString(array));

boolean flag = false; //用于标记是否进行了交换,true则说明进行了交换,false表示无

//冒泡排序
       for (int i = 0; i < array.length - 1; i++) {
           System.out.println("第" + (i+1) + "趟排序开始!");
           for (int j = 0; j < array.length - i - 1; j++) {
               //如果前面的数比后面的数大,则交换
               if(array[j] > array[j+1]){
                   //交换
                   flag = true; //标记进行了交换
                   int temp = array[j];
                   array[j] = array[j+1];
                   array[j+1] = temp;
               }
               System.out.println("------第" + (j+1) + "趟排序: " + Arrays.toString(array));
           }
           System.out.println("第" + (i+1) + "趟排序完成: " + Arrays.toString(array));
           System.out.println("================================================");
           if (!flag){
               //如果没有进行交换则直接退出,说明排序已经完成
               break;
           }else {
               //回退
               flag = false;
           }
       }

//输出排序后的结果
       System.out.println("排序后:" + Arrays.toString(array));
   }
}

四趟排序,优化成了只需要两趟排序!又是一个不可多得的小技巧!在算法程序题中,flag的设置是一种常用的编程思想,常常用于回溯算法中,小伙伴们要学会举一反三~

排序算法图解之Java冒泡排序及优化

来源:https://blog.csdn.net/m0_60353039/article/details/127670013

标签:Java,冒泡,排序
0
投稿

猜你喜欢

  • Springboot整合mybatis开启二级缓存的实现示例

    2023-02-24 13:07:18
  • Android自定义Banner轮播效果

    2023-08-05 23:34:06
  • 利用Distinct()内置方法对List集合的去重问题详解

    2023-01-31 00:45:30
  • Android实战教程第九篇之短信高效备份

    2022-02-14 12:59:20
  • Entity Framework模型优先与实体对象查询

    2022-11-18 07:19:36
  • Spring Boot从Controller层进行单元测试的实现

    2023-07-21 03:07:10
  • 在mybatis中使用mapper进行if条件判断

    2023-08-01 08:09:34
  • Android实现带指示点的自动轮播无限循环效果

    2021-12-09 19:22:44
  • 一文详解Java线程的6种状态与生命周期

    2022-02-08 08:44:30
  • java实现MD5加密的方法小结

    2022-02-26 20:01:47
  • 基于idea 的 Java中的get/set方法之优雅的写法

    2023-11-26 20:22:50
  • jenkins+Maven从SVN上构建项目的方法

    2022-07-09 04:42:37
  • 生产消费者模式实现方式和线程安全问题代码示例

    2023-11-26 19:44:17
  • Java中反射的学习笔记分享

    2021-12-18 14:41:43
  • SpringBoot雪花算法主键ID传到前端后精度丢失问题的解决

    2022-07-18 02:30:47
  • C#实现策略模式

    2022-02-09 17:19:01
  • Java深入浅出数组的定义与使用上篇

    2022-03-10 22:32:58
  • C#限速下载网络文件的方法实例

    2023-07-01 01:33:15
  • Java 精炼解读数据结构的链表的概念与实现

    2022-03-02 05:17:11
  • 浅谈HashMap、HashTable的key和value是否可为null

    2022-03-12 19:57:47
  • asp之家 软件编程 m.aspxhome.com