《糊涂算法》之八大排序——冒泡排序

Posted 一条coding

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《糊涂算法》之八大排序——冒泡排序相关的知识,希望对你有一定的参考价值。

📚 八大排序算法合集——两万字,8张动图,450行代码。大厂面试必备。

🌲 配套源码地址:《八大排序》源码,提取码:5ehp

哈喽,大家好,我是一条~

今天给大家带来《糊涂算法》专栏的第二期内容——排序算法的讲解。相信无论是初学者学习还是大厂面试,都少不了排序算法这关,即使没学过算法,对冒泡排序也不会陌生。

今天,一条就带大家彻底跨过「排序算法」这道坎,保姆级教程建议收藏。⭐️

准备

古语云:“兵马未动,粮草先行”。想跟着一条一块把「排序算法」弄明白的,建议先准备好以下代码模板。

📢 观看本教程需知道基本循环语法两数交换双指针等前置知识。

📚 建议先看完代码逐步分析后再尝试自己写。

  • 新建一个Java工程,本文全篇也基于Java语言实现代码。
  • 建立如下目录结构

  • MainTest测试类中编写测试模板。
/**
 * 测试类
 * Author:一条
 * Date:2021/09/23
 */
public class MainTest {
    public static void main(String[] args) {
        //待排序序列
        int[] array={6,10,4,5,2,8};
        //调用不同排序算法
				// BubbleSort.sort(array);

        // 创建有100000个随机数据的数组
        int[] costArray=new int[100000];
        for (int i = 0; i < 100000; i++) {
            // 生成一个[0,100000) 的一个数
            costArray[i] = (int) (Math.random() * 100000);
        }

        Date start = new Date();
        //过长,先注释掉逐步打印
				//BubbleSort.sort(costArray);
        Date end = new Date();
        System.out.println("耗时:"+(end.getTime()-start.getTime())/1000+"s");
    }
}

该段代码内容主要有两个功能:

  • 调用不同的排序算法进行测试
  • 测试不同排序算法将10w个数排好序需要的时间。更加具象的理解时间复杂度的不同

冒泡排序

基本思想

通过对乱序序列从前向后遍历,依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部。

像水底下的气泡一样逐渐向上冒一样。

动图讲解

代码实现

不理解的小伙伴可以用debug模式逐步分析。

/**
 * 冒泡排序
 * Author:一条
 * Date:2021/09/23
 */
public class BubbleSort{
    public static int[] sort(int[] array){
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array.length-1; j++) {
              //依次比较,将最大的元素交换到最后
                if (array[j]>array[j+1]){
                  // 用临时变量temp交换两个值
                    int temp=array[j];
                    array[j]=array[j+1];
                    array[j+1]=temp;
                }
            }
          //输出每一步的排序结果
            System.out.println(Arrays.toString(array));
        }
        return array;
    }
}

输出结果

逐步分析

  1. 初始数组:[6,10,4,5,2,8]
  2. 6拿出来和后一个10比较,6<10,不用交换。- > j++;
  3. 10拿出来和后一个4比较,10>4,交换。- > [6,4,10,5,2,8]
  4. 依次执行j++与后一个比较交换
  5. 第一层i循环完,打印第一行- > [6, 4, 5, 2, 8, 10],此时最后一位10在正确位置上。 - > i++
  6. 4开始,继续比较交换,倒数第二位8回到正确位置。
  7. 如上循环下去 - > ……
  8. 最终结果 - > [2, 4, 5, 6, 8, 10]

这时再回去看动图理解。

耗时测试

记得先注释掉排序类逐步打印代码。

时间复杂度O(n^2)

算法优化

优化点一

外层第一次遍历完,最后一位已经是正确的,j就不需要再比较,所以结束条件应改为j-i-1;

优化点二

因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排序过程中设置一个标志flag判断元素是否进行过交换。从而减少不必要的比较。

优化代码

public static int[] sortPlus(int[] array){
        System.out.println("优化冒泡排序开始----------");
        for (int i = 0; i < array.length; i++) {
            boolean flag=false;
            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;
                }
            }
            if (flag==false){
                break;
            }
//            System.out.println(Arrays.toString(array));
        }
        return array;
    }

优化测试

通过基础测试看到当序列已经排好序,即不发生交换后终止循环。

耗时测试由27s优化到17s


点击查看更多排序算法

以上是关于《糊涂算法》之八大排序——冒泡排序的主要内容,如果未能解决你的问题,请参考以下文章

《糊涂算法》之八大排序——插入排序

《糊涂算法》之八大排序——选择排序

《糊涂算法》之八大排序——计数排序

《糊涂算法》之八大排序——归并排序

《糊涂算法》之八大排序——快速排序

《糊涂算法》之八大排序——堆排序