详解冒泡排序算法及其java实现

简介: 冒泡排序是一种交换排序算法,元素通过两两的比较,交换不满足次序要求的元素,直到整个数组都满足次序要求为止。

一、算法思想


冒泡排序是一种交换排序算法,元素通过两两的比较,交换不满足次序要求的元素,直到整个数组都满足次序要求为止。


比如一个无序的数组中有元素[4,3,8,6,1],如果按照升序的排序顺序,则采用冒泡排序的过程则是:


第一趟排序:先是4和3比较,4比3大,则交换位置,则顺序是


                     3 4 8 6 1


然后4和8比较,8比4大,则不交换顺序,顺序还是


                     3  4 8 6 1


然后8和6比较,8比6大,则交换顺序,则顺序是


                     3  4 6  8 1


然后 8 和 1 比较 8 比1 大,则交换顺序,则顺序是


                     3  4 6 1 8


所以第一趟排序的最终结果是3 4 6 1 8,即最大的元素在最后的位置。


第二趟排序:3 和 4 比较,3 比 4小,不交换顺序,顺序不变


4 和 6 比较,4 比6 小,不交换顺序,顺序不变


6 和 1 比较,6 比 1 大,交换顺序,则顺序为 3 4 1 6 8,


6 和 8 比较,6 比 8 小,不交换顺序,则顺序为3 4 1 6 8


所以第二趟的排序结果为3 4 1 6 8,即第二大的元素在倒数第二的位置


第三趟排序  3 和 4 比较 不交换顺序


4 和 1 比较 交换顺序,交换后顺序为3 1 4 6 8


。。。。后面已经为顺序了,交换顺序不变,


所以第三趟的排序为3 1 4 6 8,即第三大的顺序在倒数第三的位置


第四趟排序   3 和 1 比较,交换顺序,交换后排序为 1 3 4 6 8,


经过四趟排序,数组为顺序数组。


二、算法分析


通过上述演示,我们可以发现当长度为N的数组的初始状态是顺序的,则一趟排序即可完成排序。比较次数为N-1和记录移动次数为0,均为最小值。所以,冒泡排序最好时间复杂度为O(N)。


当数组的初始顺序是倒叙的,则需要进行 N -1 趟排序。每趟排序要进行 N - i 次关键字的比较(1 ≤ i ≤ N - 1),每次比较都必须移动记录三次来达到交换记录位置。比较和移动次数均达到最大值N^2,所以冒泡排序的最坏时间复杂度为O(N^2)。


所以,冒泡排序的平均时间复杂度为O(N^2)。 当两个元素大小相等时,相对位置不会发生改变,所以冒泡排序是稳定的排序算法


三、Java代码


import java.util.Arrays;
/**
 * @Author: 江夏
 * @Date: 2021/11/02/20:50
 * @Description:冒泡排序算法
 */
public class MaoPaoSort {
    public static void main(String[] args) {
        int testTime=500000;
        int size = 10;
        int value=100;
        boolean succeed = true;
        for(int i = 0 ;i<testTime;i++){
            int[] arr1 = generateRandomArray(size,value);
            int[] arr2 = copyArray(arr1);
            int[] arr3= copyArray(arr1);
            bubbleSort(arr1);
            rightMethod(arr2);
            if(!isEqual(arr1,arr2)){
                succeed=false;
                printArray(arr3);
                break;
            }
        }
        int[] arr= generateRandomArray(size,value);
        printArray(arr);
        bubbleSort(arr);
        printArray(arr);
    }
    //产生一个随机数组,数组的长度和值都是随机的,
    public static  int[] generateRandomArray(int size,int value){
        int[] arr = new int[(int)((size+1)*Math.random())];
        for(int i = 0 ;i<arr.length;i++){
            //值也可以是随机的
            arr[i]=(int)((value+1)*Math.random())-(int)(value*Math.random());
        }
        return arr;
    }
    //复制数组
    public static int[] copyArray(int[] arr){
        if(arr==null){
            return null;
        }
        int[] res = new int[arr.length];
        for(int i = 0 ;i<arr.length;i++){
            res[i]=arr[i]  ;
        }
        return res;
    }
    public static void rightMethod(int[] arr){
        Arrays.sort(arr);
    }
    public static boolean isEqual(int[] arr1,int[] arr2){
        if(arr1==null&&arr2!=null||arr1!=null&&arr2==null){
            return false;
        }
        if (arr1==null&&arr2==null){
            return true;
        }
        if (arr1.length!=arr2.length){
            return false;
        }
        for(int i = 0;i<arr1.length;i++){
            if(arr1[i]!=arr2[i]){
                return false;
            }
        }
        return true;
    }
    //打印出数组
    public static void printArray(int[] arr){
        if(arr==null){
            return;
        }
        for(int i = 0 ;i<arr.length;i++){
            System.out.print(arr[i]+" ");
        }
        System.out.println();
    }
    //N个数字冒泡排序,总共要进行N-1趟比较,每趟的排序次数为(N-i)次比较
    public static void bubbleSort(int[] arr){
        if(arr==null||arr.length<2){
            return;
        }
        //需要进行arr.length趟比较
        for(int i = 0 ;i<arr.length-1;i++){
            //第i趟比较
            for(int j = 0 ;j<arr.length-i-1;j++){
                //开始进行比较,如果arr[j]比arr[j+1]的值大,那就交换位置
                if(arr[j]>arr[j+1]){
                    int temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                }
            }
        }
    }
    public static  void rightMathods(int[] arr){
        //调用系统调用的函数来进行验证
        Arrays.sort(arr);
    }
}
复制代码


运行结果如下:

476d5633993944609f6e6b149d9c0a72~tplv-k3u1fbpfcp-zoom-in-crop-mark_1304_0_0_0.webp (1).jpg


四 总结


冒泡排序原理就是比较两个相邻的元素,将值大的元素交换到右边,因为这种排序相等的元素不进行交换,所以它是一种稳定排序


冒泡排序的优点:每进行一趟排序,就会少比较一次,因为每进行一趟排序都会找出一个较大值。一定程度上减少了算法的量。


如果元素刚好都是正序排序,只需要走一趟即可完成排序。所需的比较次数C和记录移动次数M均达到最小值,即:Cmin=n-1;Mmin=0;所以,冒泡排序最好的时间复杂度为O(n)。


如果元素都是反序排序,则需要进行n-1趟排序。每趟排序要进行n-i次比较(1≤i≤n-1),且每次比较都必须移动记录三次来达

到交换记录位置。在这种情况下,比较和移动次数均达到最大值:  

 

 175267ad965b46f8bb6fde9b0c953ab0~tplv-k3u1fbpfcp-zoom-in-crop-mark_1304_0_0_0.webp.jpg


所以冒泡排序总的平均时间复杂度为:O(n2)(n的平方)。


以上就是关于冒泡排序的介绍!


目录
相关文章
|
2月前
|
存储 人工智能 算法
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
这篇文章详细介绍了Dijkstra和Floyd算法,这两种算法分别用于解决单源和多源最短路径问题,并且提供了Java语言的实现代码。
90 3
数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
|
2月前
|
搜索推荐
冒泡排序算法
【10月更文挑战第19天】冒泡排序是一种基础的排序算法,虽然在实际应用中可能不是最优的选择,但对于理解排序算法的基本原理和过程具有重要意义。
|
2月前
|
机器学习/深度学习 算法 搜索推荐
让星星⭐月亮告诉你,Java冒泡排序及其时间复杂度计算
冒泡排序是一种简单的排序算法,通过多次遍历数组,每次比较相邻元素并交换位置,将较小的元素逐步移至数组前端。第一轮结束后,最小值会位于首位;第二轮则将次小值置于第二位,依此类推。经过 (n-1) 轮遍历后,数组完成排序。冒泡排序的时间复杂度为 O(n²),在最优情况下(已排序数组)时间复杂度为 O(n)。示例代码展示了如何实现冒泡排序。
54 1
|
2月前
|
算法 Java
java冒泡排序与二分查找(详解)
java冒泡排序与二分查找(详解)
40 4
|
2月前
|
算法 搜索推荐 Java
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
这篇文章介绍了如何使用Java后端技术,结合Graphics2D和Echarts等工具,生成包含个性化信息和图表的海报,并提供了详细的代码实现和GitHub项目链接。
128 0
java 后端 使用 Graphics2D 制作海报,画echarts图,带工具类,各种细节:如头像切割成圆形,文字换行算法(完美实验success),解决画上文字、图片后不清晰问题
|
2月前
|
算法 搜索推荐
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
本文介绍了冒泡排序、选择排序和插入排序三种基础排序算法的原理、实现代码和测试结果。
21 0
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
|
2月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
84 2
|
2月前
|
算法 Java Linux
java制作海报一:java使用Graphics2D 在图片上写字,文字换行算法详解
这篇文章介绍了如何在Java中使用Graphics2D在图片上绘制文字,并实现自动换行的功能。
133 0
|
2月前
|
搜索推荐 C语言
排序算法--冒泡排序
排序算法--冒泡排序
18 0
|
2月前
|
存储 搜索推荐 算法
【排序算法(二)】——冒泡排序、快速排序和归并排序—>深层解析
【排序算法(二)】——冒泡排序、快速排序和归并排序—>深层解析