优化常见的java排序算法

优化常见的Java排序算法

排序算法是计算机科学中最基础、也是最常用的算法之一。Java提供了多种排序算法的实现,如冒泡排序、插入排序、选择排序、快速排序、归并排序等。但是,这些算法的标准实现在某些情况下可能效率比较低,需要进行优化。

一、冒泡排序

冒泡排序是一种交换排序,基本思想是将相邻的元素两两比较,如果前面的元素大于后面的元素,则交换它们的位置,直到没有相邻元素需要比较为止。冒泡排序时间复杂度为O(n^2)。

优化方案:

  1. 设置标志位,在每次交换元素时标记一下。如果没有元素需要交换,跳出循环。这样可以减少不必要的比较,提高算法效率。
public static void bubbleSortImproved(int[] arr) {
    int n = arr.length;
    boolean swapped = true;
    for (int i = 0; i < n - 1 && swapped; i++) {
        swapped = false;
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr, j, j + 1);
                swapped = true;
            }
        }
    }
}
  1. 每次排序保存最后一次交换位置,下一轮排序时只需要比较到这个位置,后面的元素已经排序好了。这样可以减少比较次数,提高算法效率。
public static void bubbleSortImproved(int[] arr) {
    int n = arr.length;
    int lastSwappedIndex = n - 2;
    for (int i = 0; i < n - 1; i++) {
        int currSwappedIndex = -1;
        for (int j = 0; j <= lastSwappedIndex; j++) {
            if (arr[j] > arr[j + 1]) {
                swap(arr, j, j + 1);
                currSwappedIndex = j;
            }
        }
        lastSwappedIndex = currSwappedIndex;
        if (lastSwappedIndex == -1) {
            break;
        }
    }
}

二、快速排序

快速排序是一种常见的分治排序算法,基本思想是通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,然后分别对这两部分继续进行排序,以达到整个序列有序的目的。快速排序时间复杂度平均为O(nlogn),最坏情况下为O(n^2)。

优化方案:

  1. 优化基准值的选择。可以使用三数取中法来选择基准值,即从左、右、中间三个元素中选择中间值作为基准值。这样可以避免极端情况下基准值选择不当导致的效率问题。
private static void quickSortImproved(int[] arr, int left, int right) {
    if (right - left < 2) {
        return;
    }
    int midIndex = getMidIndex(arr, left, right);
    int pivot = arr[midIndex];
    swap(arr, midIndex, right - 1);

    int i = left;
    int j = right - 1;
    while (true) {
        while (arr[++i] < pivot) {}
        while (arr[--j] > pivot) {}
        if (i < j) {
            swap(arr, i, j);
        } else {
            break;
        }
    }
    swap(arr, i, right - 1);
    quickSortImproved(arr, left, i - 1);
    quickSortImproved(arr, i + 1, right);
}
private static int getMidIndex(int[] arr, int left, int right) {
    int mid = (left + right) / 2;
    if (arr[left] > arr[mid]) {
        swap(arr, left, mid);
    }
    if (arr[left] > arr[right - 1]) {
        swap(arr, left, right - 1);
    }
    if (arr[mid] > arr[right - 1]) {
        swap(arr, mid, right - 1);
    }
    return mid;
}
  1. 优化小数组的排序。当子序列长度小于一定值时,可以使用插入排序来代替快速排序,这样可以减少递归调用带来的额外开销。
private static void quickSortImproved(int[] arr, int left, int right) {
    if (right - left < 2) {
        return;
    }
    if (right - left < 10) {
        insertionSort(arr, left, right);
        return;
    }

    int midIndex = getMidIndex(arr, left, right);
    int pivot = arr[midIndex];
    swap(arr, midIndex, right - 1);

    int i = left;
    int j = right - 1;
    while (true) {
        while (arr[++i] < pivot) {}
        while (arr[--j] > pivot) {}
        if (i < j) {
            swap(arr, i, j);
        } else {
            break;
        }
    }
    swap(arr, i, right - 1);
    quickSortImproved(arr, left, i - 1);
    quickSortImproved(arr, i + 1, right);
}
private static void insertionSort(int[] arr, int left, int right) {
    for (int i = left + 1; i < right; i++) {
        int temp = arr[i];
        int j;
        for (j = i; j > left && temp < arr[j - 1]; j--) {
            arr[j] = arr[j - 1];
        }
        arr[j] = temp;
    }
}

两条示例说明:

int[] arr1 = {5, 3, 4, 2, 1};
BubbleSort.bubbleSortImproved(arr1);
System.out.println(Arrays.toString(arr1));  // [1, 2, 3, 4, 5]

int[] arr2 = {5, 3, 4, 2, 1};
QuickSort.quickSortImproved(arr2);
System.out.println(Arrays.toString(arr2));  // [1, 2, 3, 4, 5]

以上是优化常见的Java排序算法的攻略,通过实现这些优化方案,可以有效提高排序算法的效率,应用到实际项目中可以更好地满足用户需求。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:优化常见的java排序算法 - Python技术站

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

相关文章

  • IDEA中的.iml文件和.idea文件夹

    下面我详细讲解一下“IDEA中的.iml文件和.idea文件夹”的完整攻略。 什么是.iml文件和.idea文件夹 在使用IntelliJ IDEA创建一个Java工程时,IDEA会自动生成 .iml 文件和 .idea 文件夹。.iml 文件是 IntelliJ IDEA 工程的描述文件,.idea 文件夹包含了整个工程的配置文件。 .iml文件的内容 .…

    Java 2023年5月19日
    00
  • 详解SpringBoot中时间类型的序列化与反序列化

    下面是关于“详解 Spring Boot 中时间类型的序列化与反序列化”的攻略。 为什么需要时间类型的序列化和反序列化 在 Web 开发中,时间类型的数据在 HTTP 请求和响应中经常使用。常见的时间类型有 java.util.Date、java.sql.Date、java.sql.Timestamp、java.time.LocalDateTime 等。我们…

    Java 2023年5月20日
    00
  • JavaScript实现简易登录注册页面

    针对“JavaScript实现简易登录注册页面”的完整攻略,我将按照以下方式进行讲解: 确定页面元素和功能 实现登录和注册功能 数据存储和验证 示例说明 确定页面元素和功能 在实现登录注册功能之前,我们需要先明确需要哪些页面元素和功能。通常登录注册页面需要的元素包括: 用户名输入框 密码输入框 登录按钮 注册按钮 其中登录按钮需要进行用户名和密码验证,如果验…

    Java 2023年6月15日
    00
  • Spring整合mybatis实现过程详解

    下面是“Spring整合mybatis实现过程详解”的完整攻略。 简介 Spring和MyBatis是两个非常流行的Java框架,常常被用来搭建底层的Web应用程序。其中,Spring作为一种IOC容器和AOP框架,可以管理Java中的对象,控制对象之间的依赖关系,以及提供统一的事务管理等功能;而MyBatis则是一种ORM框架,可以将Java对象映射到关系…

    Java 2023年5月19日
    00
  • java如何更改数据库中的数据

    想要更改数据库中的数据,需要使用Java中的数据库操作技术,以下是详细的步骤: 1. 准备工作 首先需要确保Java项目中已经引入了数据库操作相关的依赖,例如JDBC。其次需要配置数据库连接信息,包括数据库驱动、数据库地址、用户名和密码等。 2. 连接数据库 使用Java代码连接数据库,可以使用JDBC提供的java.sql.Connection接口。例如:…

    Java 2023年5月19日
    00
  • java获取当前时间的四种方法代码实例

    下面是完整的攻略。 介绍 在Java中,我们常常需要获取当前的时间,用于记录日志、统计应用程序的运行时长等等。本文将介绍四种获取当前时间的方法,并提供相应的代码实例。 方法一:使用System类的currentTimeMillis()方法获取当前时间 System类提供了一个静态的currentTimeMillis()方法,可以获取当前的毫秒数,从而计算出当…

    Java 2023年5月20日
    00
  • springboot jta atomikos实现分布式事物管理

    下面是讲解“springboot jta atomikos实现分布式事物管理”的完整攻略。 简介 分布式事务管理是一个很常见的需求,使用 JTA(Java Transaction API)接口可以比较容易地实现分布式事务管理,而 Atomikos 是一个比较流行的 JTA 事务管理器。 在 Spring Boot 中,我们可以基于 Atomikos 实现分布…

    Java 2023年5月20日
    00
  • 详解Func与Action区别

    当我们编写C#代码时,经常会遇到Func<T>和Action<T>这两个委托类型。它们都是 C# 环境中的通用委托类型,用于定义具有特定签名的同步方法。虽然它们在某些方面看起来相似,但实际上它们之间有一些重要的区别。 Func与Action的区别 Func和Action的定义 Func:表示一个带有返回值的函数的委托。它可以在不使用自…

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