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

yizhihongxing

我来为你详细讲解“排序算法图解之Java冒泡排序及优化”的完整攻略。

简介

排序算法在计算机学科中是非常重要的内容,冒泡排序就是其中的一种,设计简单,易于理解和实现,其时间复杂度为O(n^2)。本篇文章主要介绍了Java语言实现冒泡排序的方式以及针对普通冒泡排序算法的优化。

冒泡排序

冒泡排序是稳定排序中的一种,其基本操作是将相邻的元素进行比较和交换,每次循环可以保证一个元素就位。具体操作如下:

  1. 从列表的第一个元素开始,依次比较相邻的两个元素,如果第一个元素大于第二个元素,则交换这两个元素;
  2. 继续逐个比较相邻的元素,直到遍历到列表的倒数第二个元素;
  3. 上述操作会使得列表的最大元素位于列表的末尾;
  4. 重复上述过程,直到整个列表有序。

下面是Java代码实现冒泡排序:

public static void bubbleSort(int[] arr) {
    int n = arr.length;
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

其中,arr表示待排序的列表,n表示列表的长度。

冒泡排序的优化

虽然冒泡排序是一种简单直观的排序算法,但其时间复杂度为O(n^2),在处理大规模数据时效率并不高。下面是两种常见的冒泡排序优化方法:

优化一:添加标记位

当列表已经有序时,冒泡排序仍然会执行完所有的比较和交换操作,此时可以通过添加标记位来优化算法时间复杂度,具体操作如下:

  1. 初始化标记位为false
  2. 从列表的第一个元素开始,依次比较相邻的两个元素,如果第一个元素大于第二个元素,则交换这两个元素,并将标记位置为true
  3. 如果当前循环中没有发生交换操作,则列表已经有序,直接退出循环;
  4. 重复上述操作,直到整个列表有序。

下面是Java代码实现冒泡排序优化:

public static void bubbleSortOptimize1(int[] arr) {
    int n = arr.length;
    boolean flag = false;
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                flag = true;
            }
        }
        if (!flag) {
            break;
        }
        flag = false;
    }
}

优化二:记录最后一次交换位置

在一次循环过程中,如果发现有多组元素需要交换,那么应该让最小的元素尽可能地往前调整,这样可以避免每次循环交换多组元素时总是将最小元素调到列表的末尾。具体操作如下:

  1. 初始化最后一次交换位置为列表的尾部位置n
  2. 从列表的第一个元素开始,依次比较相邻的两个元素,如果第一个元素大于第二个元素,则交换这两个元素,并更新最后一次交换位置;
  3. 如果当前循环中没有发生交换操作,则列表已经有序,直接退出循环;
  4. 将最后一次交换位置更新为当前循环中进行交换操作的最后一组交换位置;
  5. 重复上述操作,直到整个列表有序。

下面是Java代码实现冒泡排序优化:

public static void bubbleSortOptimize2(int[] arr) {
    int n = arr.length;
    int lastExchangeIndex = n;
    for (int i = 0; i < n - 1; i++) {
        boolean flag = false;
        int temp = lastExchangeIndex;
        for (int j = 0; j < temp - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                int t = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = t;
                flag = true;
                lastExchangeIndex = j + 1;
            }
        }
        if (!flag) {
            break;
        }
    }
}

示例说明

示例一

假设待排序的列表为[2, 3, 1, 5, 4],那么经过一个循环之后,列表变成了[2, 1, 3, 4, 5],这里只展示了第一个最大元素2的位置,下一个循环会将第二大元素5调整到列表的倒数第二个位置。这个过程称为一次冒泡过程,该列表的冒泡过程需要进行4次,才能得到有序的列表。具体示例如下:

待排序列表 第一次冒泡过程 第二次冒泡过程 第三次冒泡过程 第四次冒泡过程
[2, 3, 1, 5, 4] [2, 1, 3, 4, 5] [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]

可以看到,在第一次冒泡过程中,列表的第一个元素2被调整到了倒数第二个位置,而元素5并没有发生交换。这就说明,在元素2被调整到了列表的倒数第二个位置之后,列表的后半部分已经有序了,所以在后面的冒泡过程中就不需要再次比较和交换后半部分的元素。

示例二

假设待排序的列表为[5, 2, 4, 6, 1, 3],那么经过优化一之后的冒泡排序,只需要进行三次冒泡过程就可以得到有序列表[1, 2, 3, 4, 5, 6]。在第三次冒泡过程中,列表元素[4, 5, 6]已经有序,所以在后面的冒泡过程中就不需要再比较和交换这几个元素。具体示例如下:

待排序列表 第一次冒泡过程 第二次冒泡过程 第三次冒泡过程
[5, 2, 4, 6, 1, 3] [2, 4, 5, 1, 3, 6] [2, 4, 1, 3, 5, 6] [2, 1, 3, 4, 5, 6]

可以发现,优化一让排序时间复杂度大大降低,通过添加标记位可以避免多余的比较和交换操作,提高了算法的效率。

结语

冒泡排序虽然时间复杂度比较高,但其算法思想简单直观,容易实现和理解。本篇文章为大家详细介绍了Java语言实现冒泡排序的方式以及针对普通冒泡排序算法的两种优化方法,希望能对大家学习排序算法有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:排序算法图解之Java冒泡排序及优化 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • 使用jquery-easyui的布局layout写后台管理页面的代码详解

    使用jquery-easyui的布局layout写后台管理页面的代码详解: 一、概述 在开发后台管理系统时,使用jquery-easyui的布局layout可以大幅度简化代码编写和调试过程。本文将从安装、配置、创建布局、添加面板等方面详细介绍使用jquery-easyui的布局layout进行后台管理设计的攻略。 二、安装和配置 1.引入jquery、jqu…

    Java 2023年6月15日
    00
  • 自定义一个简单的JDBC连接池实现方法

    自定义 JDBC 连接池是一项非常重要的任务,它可以帮助开发人员管理数据库连接并提高系统性能。下面是自定义一个简单的 JDBC 连接池的步骤和示例: 步骤 创建一个 ConnectionPool 类用于管理数据库连接。 在 ConnectionPool 类中创建一个空闲连接池来保存未使用的连接。 在 ConnectionPool 类中创建一个活动连接池来保存…

    Java 2023年6月1日
    00
  • jsp Hibernate批量更新和批量删除处理代码

    下面我将为您详细讲解“jsp Hibernate批量更新和批量删除处理代码”的完整攻略。 什么是Hibernate? Hibernate是一个开源的面向关系型数据库的Java对象关系映射(ORM)框架,它将Java类与数据库表映射,将Java对象与数据库记录进行转换。使用Hibernate可以让我们像操作Java对象一样操作数据库,从而提高开发效率。 批量更…

    Java 2023年6月15日
    00
  • 一文带你搞懂Java8的LocalDateTime

    一文带你搞懂Java8的LocalDateTime 什么是LocalDateTime LocalDateTime是Java 8提供的一个时间类型,表示本地日期和时间,不包含时区信息。它是LocalDate和LocalTime的结合体,提供了更加方便的操作方式和更加清晰的概念。 获取LocalDateTime实例 使用LocalDateTime.now()方法…

    Java 2023年5月20日
    00
  • springboot集成mybatisplus的详细步骤

    关于如何在Spring Boot项目中集成MyBatis Plus,其详细步骤如下: 引入依赖 在 pom.xml 中添加以下依赖: <!– Mybatis Plus –> <dependency> <groupId>com.baomidou</groupId> <artifactId>myba…

    Java 2023年5月20日
    00
  • jsp登录页面的简单实例 雏形

    下面就让我来详细讲解 “JSP登录页面的简单实例 雏形”的完整攻略。 1. 需求分析 在设计登录页面之前,我们需要先进行需求分析。先明确一下这个登录页面需要哪些功能,如输入用户名和密码,验证用户登录信息等。 2. 设计页面 接着设计登录页面的样式和布局。可以使用Bootstrap等前端框架提供的CSS样式和布局,或者自己手动编写CSS。 3. 开发登录页面 …

    Java 2023年6月15日
    00
  • java的新特性反射机制应用及操作示例详解

    Java 的反射机制 什么是反射机制 反射机制是一种使 Java 非常强大且灵活的技术。反射机制允许在运行时动态地获取类的属性、方法和构造函数,同时也可以动态地调用这些方法、属性和构造函数。 反射机制使用 java.lang.reflect 包获取一个类的相关信息。反射的一些常见应用包括:动态代理、单元测试和框架开发。在框架开发中,我们通常会在编译时不知道某…

    Java 2023年5月26日
    00
  • Maven发布Jar包中文乱码解决方法

    下面我来详细讲解“Maven发布Jar包中文乱码解决方法”的完整攻略。 问题描述 当我们使用Maven打包发布Jar包时,有时会出现中文乱码的现象。这种现象出现的原因是在打包过程中,Maven使用的编码和实际项目使用的编码不一致,导致编码转换错误。因此,我们需要对这种问题进行解决。 解决方法 我们可以通过在Maven的pom.xml配置文件中添加如下代码来解…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部