首页 > 编程语言 >经典再现,回顾常见排序算法之冒泡排序,附Java源码及优化改进实现

经典再现,回顾常见排序算法之冒泡排序,附Java源码及优化改进实现

时间:2024-07-12 10:28:03浏览次数:16  
标签:Java 不需 int 交换 冒泡排序 源码 排序 比较

回顾一下排序算法,老酒装新瓶,给自己的技能点做个回放。

排序(Sorting) 是计算机程序设计中的一种重要操作,它的功能是将一个数据元素(或记录)的任意序列,重新排列成一个有序的序列,也可以理解为高矮个站队。

衡量排序算法的两个指标,时间复杂度 和 稳定性。

举个例子,如果我们的数据是:3 5 4 2 2, 稳定的排序最后的俩个2在排好序后他们的原始前后顺序是不会变的(第一个2还在第二个2的前面,有点绕,你可以理解为小明和小强一样高,最开始小明在小强的前面,排完序之后,小明还在小强前面,就属于稳定的排序),不稳定的排序最后两个2的顺序可能交换(也就是可能小明在前,也可能小强在前)。

时间复杂度先跳过哈,我回头单独写一篇文章介绍,本文主要介绍和实操“冒泡排序”。

介绍

冒泡排序是將比較大的數字移到序列的后面,较小的移到前面。

从第一个开始,第一个和第二个比,谁高(大)谁站后面(两个人(数)的位置交换,不是最后面),当前第二个再与第三个比,依次进行,一轮下来之后,筛选出来最高个(大)的人(数)。

上面就表示第一轮结束了,第二轮和第一轮一样,只是最后一个人(数)已经排好了,不用管他了。

经过 N-1 轮之后,排序完成。

N 个人,经过 N-1 轮,相当于 N*(N-1)=N^2-N, 时间复杂度取最大的 O(n^2)

实例

原始数据:

3 5 2 6 2

第一轮

比较 3 和 5,5 大于 3 ,不需交换

3 5 2 6 2

继续比较 5 和 2,5 大于 2,交换位置

3 2 5 6 2

继续比较 5 和 6,6 大于 5,不需交换

3 2 5 6 2

继续比较 6 和 2,6 大于 2,交换位置

3 2 5 2 6

6 移到最后,两个2都分别向前移动。

第二轮

比较 3 和 2, 3 大于 2,交换位置

2 3 5 2 6

比较 3 和 5, 5 大于 3,不需交换

2 3 5 2 6

比较 5 和 2, 5 大于 2,交换位置

2 3 2 5 6

不需比较 5 和 6

第三轮

比较 2 和 3, 3 大于 2,不需交换

2 3 2 5 6

比较 3 和 2, 3 大于 2,交换位置

2 2 3 5 6

不需比较了

第四轮

比较 2 和 2,不需交换

2 2 3 5 6

四轮结束,最终的结果:

2 2 3 5 6

Java 实现

public class Bubble {

    /**
     * 冒泡排序
     */
    public static int[] sort(int[] array) {
        int temp;
        // 第一层循环表明比较的轮数, 比如 length 个元素,比较轮数为 length-1 次(不需和自己比)
        for (int i = 0; i < array.length - 1; i++) {
            System.out.println("第" + (i + 1) + "轮开始");
            // 第二层循环,每相邻的两个比较一次,次数随着轮数的增加不断减少,每轮确定一个最大的,不需比较那个最大的
            for (int j = 0; j < array.length - 1 - i; j++) {
                System.out.println("第" + (i + 1) + "轮,第" + (j + 1) + "次比较:");
                if (array[j + 1] < array[j]) {
                    temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
                for (int k : array) {
                    System.out.print(k + " ");
                }
                System.out.println();
            }
            System.out.println("结果:");
            for (int k : array) {
                System.out.print(k + " ");
            }
            System.out.println();
        }
        return array;
    }

    public static void main(String[] args) {
        int[] array = {3, 5, 2, 6, 2};
        int[] sorted = sort(array);
        System.out.println("最终结果");
        for (int i : sorted) {
            System.out.print(i + " ");
        }
    }

}

输出结果:

第1轮开始
第1轮,第1次比较:
3 5 2 6 2 
第1轮,第2次比较:
3 2 5 6 2 
第1轮,第3次比较:
3 2 5 6 2 
第1轮,第4次比较:
3 2 5 2 6 
结果:
3 2 5 2 6 
第2轮开始
第2轮,第1次比较:
2 3 5 2 6 
第2轮,第2次比较:
2 3 5 2 6 
第2轮,第3次比较:
2 3 2 5 6 
结果:
2 3 2 5 6 
第3轮开始
第3轮,第1次比较:
2 3 2 5 6 
第3轮,第2次比较:
2 2 3 5 6 
结果:
2 2 3 5 6 
第4轮开始
第4轮,第1次比较:
2 2 3 5 6 
结果:
2 2 3 5 6 
最终结果
2 2 3 5 6 

优化改进

对冒泡排序常见的改进方法是加入一标志性变量 pos ,用于标志某一趟排序过程中是否有数据交换,如果进行某一趟排序时并没有进行数据交换(都不需要交换,肯定排好了),则说明数据已经按要求排列好,可立即结束排序,避免不必要的比较过程。

设置一标志性变量 pos,用于记录每趟排序中最后一次进行交换的位置(后面有多个没有发生交换,说明后面已经排好了)。由于 pos 位置之后的记录均已交换到位,故在进行下一趟排序时只要排到 pos 位置即可。

怎么理解呢?

3 2 4 5 6 为例

第一轮排序,发生交换的位置仅仅是 3 和 2, 则 pos 是 0(索引位置从0开始)

直接一轮就结束了,而不用傻傻的再跑4轮。

代码实现:

public class Bubble {


    /**
     * 冒泡排序(优化改进版)
     */
    public static int[] sort(int[] array) {
        int temp;
        int time = 1;
        for (int i = array.length - 1; i > 0; ) {
            System.out.println("第" + time + "轮开始");
            int pos = 0;
            // 第二层循环,每相邻的两个比较一次,次数随着轮数的增加不断减少,每轮确定一个最大的,不需比较那个最大的
            for (int j = 0; j < i; j++) {
                System.out.println("第" + time + "轮,第" + (j + 1) + "次比较:");
                if (array[j + 1] < array[j]) {
                    // 记录最后一次交换位置的索引,下一轮只需排序到 pos 位置
                    pos = j;
                    temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
                for (int k : array) {
                    System.out.print(k + " ");
                }
                System.out.println();
            }
            // 之前是 i--, 优化后直接跳到最后交换位置的索引
            i = pos;
            time++;
            System.out.println("结果:");
            for (int k : array) {
                System.out.print(k + " ");
            }
            System.out.println();
        }
        return array;
    }

    public static void main(String[] args) {
        int[] array = {3, 2, 4, 5, 6};
        int[] sorted = sort(array);
        System.out.println("最终结果");
        for (int i : sorted) {
            System.out.print(i + " ");
        }
    }

}

结果输出:

第1轮开始
第1轮,第1次比较:
2 3 4 5 6 
第1轮,第2次比较:
2 3 4 5 6 
第1轮,第3次比较:
2 3 4 5 6 
第1轮,第4次比较:
2 3 4 5 6 
结果:
2 3 4 5 6 
最终结果
2 3 4 5 6 

总结

好了,今天的分享就这些,关于冒泡排序,你学会了嘛?如果学会了,看懂了,请留下你的点赞,收藏,分享,关注。

有任何问题可以公作号:新质程序猿,可以找到我。

标签:Java,不需,int,交换,冒泡排序,源码,排序,比较
From: https://blog.csdn.net/radapp/article/details/140358893

相关文章

  • 一类账户认证API在Java、Python、PHP中的使用教程
    随着金融科技的快速发展,一类账户认证在金融服务中扮演着越来越重要的角色。对于个人和企业而言,拥有一个高级别的账户不仅能提高交易效率,还能享受到更多优惠和服务。然而,这也带来了账户安全的挑战和风险。为了确保账户的真实性和合法性,一类账户认证应运而生。它通过对用户......
  • Java计算机毕业设计的网上电影售票系统(开题报告+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展和人们生活节奏的加快,网络购物、在线娱乐等数字化生活方式已成为主流。电影作为大众喜爱的文化娱乐形式之一,其售票方式也经......
  • Java计算机毕业设计信息工程学院实验室管理系统(开题+源码+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着信息技术的飞速发展,信息工程学院作为培养未来科技人才的重要基地,其实验室管理日益复杂化与多样化。传统的手工管理方式已难以满足高效、精准、安......
  • Java中的枚举类型详解
    Java中的枚举类型详解大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在Java中,枚举类型(enum)是一种特殊的数据类型,它允许变量定义为预定义的常量集合。枚举在Java中非常有用,特别是当需要一组固定的常量时,如方向(北、东、南、西)、颜色(红、绿、蓝)等。本文将详......
  • Java中的接口和抽象类详解
    Java中的接口和抽象类详解大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在Java编程中,接口和抽象类是非常重要的两个概念,它们在面向对象编程中起着关键作用。本文将详细介绍接口和抽象类的定义、使用方法以及它们之间的区别。1.接口的定义和使用接口......
  • 转-Java 异常处理的 20 个最佳实践,你知道几个?
    ‍作者:武培轩出处:https://www.cnblogs.com/wupeixuan原文链接:https://www.cnblogs.com/wupeixuan/p/11746117.html异常处理是Java开发中的一个重要部分,是为了处理任何错误状况,比如资源不可访问,非法输入,空输入等等。Java提供了几个异常处理特性,以try,catch和finall......
  • 基于java+springboot+vue实现的在线教育系统(文末源码+Lw)111
    基于SpringBoot+Vue的实现的在线教育系统(源码+数据库+万字Lun文+流程图+ER图+结构图+演示视频+软件包)系统功能:本在线教育系统管理员功能有个人中心,用户管理,讲师管理,普通管理员管理,课程管理员管理,课程管理,课程分类管理,教师管理,名师管理,系统管理,订单管理。普通管理员和课程......
  • 基于java+springboot+vue实现的作业管理系统(文末源码+Lw)110
    基于SpringBoot+Vue的实现的作业管理系统(源码+数据库+万字Lun文+流程图+ER图+结构图+演示视频+软件包)功能描述:作业管理系统有管理员,教师,学生三个角色。教师和学生都可以进行注册然后再登录。学生可以修改自己的密码,查看和下载作业信息,并且可以提交自己写好的作业,并且可以......
  • 2-ArrayList底层结构和源码分析
    2-ArrayList底层结构和源码分析介绍汇总:ArrayList的注意事项ArrayList的运行重要步骤补充1-ArrayList的注意事项ArrayList允许添加所有的元素,包括null,而且还可以多个null。ArrayList是由数组来实现数据存储的。ArrayList基本等同于Vector,除了ArrayList是线......
  • Java 算法和数据结构 答案整理,最新面试题
    Java中如何使用动态规划求解背包问题?1、定义子问题:首先确定动态规划状态,通常以物品数量和背包容量为变量定义子问题,例如dp[i][j]表示前i件物品放入容量为j的背包所能获得的最大价值。2、确定状态转移方程:基于是否选择当前物品,将问题分为两个子问题,即dp[i][j]=......