Java各种排序算法汇总(冒泡,选择,归并,希尔及堆排序等)

Java各种排序算法汇总

本文将详细讲解Java中常见的各种排序算法,包括冒泡排序、选择排序、归并排序、希尔排序、堆排序等,以及他们的实现代码和时间复杂度分析。

冒泡排序

冒泡排序是一种基础的排序算法,核心思想是将相邻的元素两两比较,将较大的元素向后移动。代码如下:

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

时间复杂度为O(n^2),不适用于大量数据的排序。

选择排序

选择排序的核心思想是每次选择一个最小/最大的元素,在未排序的元素中寻找最小/最大的元素,将其放置于序列起始位置。代码如下:

public static void selectionSort(int[] array) {
    for (int i = 0; i < array.length - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < array.length; j++) {
            if (array[j] < array[minIndex]) {
                minIndex = j;
            }
        }
        if (minIndex != i) {
            int temp = array[i];
            array[i] = array[minIndex];
            array[minIndex] = temp;
        }
    }
}

时间复杂度为O(n^2),比较次数与冒泡排序相同,但是交换次数会减少。

归并排序

归并排序是一种基于分治思想的排序算法,核心思想是将待排序的序列分成若干个子序列,每个子序列都是有序的,然后合并子序列成一个整体有序的序列。代码如下:

public static void mergeSort(int[] array, int left, int right) {
    if (left < right) {
        int mid = (left + right) / 2;
        mergeSort(array, left, mid);
        mergeSort(array, mid + 1, right);
        merge(array, left, mid, right);
    }
}

public static void merge(int[] array, int left, int mid, int right) {
    int[] temp = new int[right - left + 1];
    int i = left;
    int j = mid + 1;
    int k = 0;
    while (i <= mid && j <= right) {
        if (array[i] < array[j]) {
            temp[k++] = array[i++];
        } else {
            temp[k++] = array[j++];
        }
    }
    while (i <= mid) {
        temp[k++] = array[i++];
    }
    while (j <= right) {
        temp[k++] = array[j++];
    }
    System.arraycopy(temp, 0, array, left, temp.length);
}

时间复杂度为O(nlogn),稳定性好,但是需要使用额外的空间。

希尔排序

希尔排序是一种基于插入排序的排序算法,核心思想是将待排序的序列分成若干个增量序列,对每个增量序列进行插入排序,最后当增量为1时,整个序列排成一个有序序列。代码如下:

public static void shellSort(int[] array) {
    int gap = array.length / 2;
    while (gap > 0) {
        for (int i = gap; i < array.length; i++) {
            int j = i;
            int temp = array[j];
            if (array[j] < array[j - gap]) {
                while (j - gap >= 0 && temp < array[j - gap]) {
                    array[j] = array[j - gap];
                    j -= gap;
                }
                array[j] = temp;
            }
        }
        gap = gap / 2;
    }
}

时间复杂度比较复杂,平均情况下为O(nlogn)。

堆排序

堆排序是一种基于完全二叉树结构的排序算法,核心思想是将待排序的元素构建成一个堆,然后依次取出堆顶元素,加入有序序列中。代码如下:

public static void heapSort(int[] array) {
    int len = array.length - 1;
    for (int i = len / 2; i >= 0; i--) {
        heapAdjust(array, i, len);
    }
    for (int i = len; i > 0; i--) {
        int temp = array[0];
        array[0] = array[i];
        array[i] = temp;
        heapAdjust(array, 0, i - 1);
    }
}

public static void heapAdjust(int[] array, int parent, int len) {
    int temp = array[parent];
    int child = 2 * parent + 1;
    while (child <= len) {
        if (child + 1 <= len && array[child] < array[child + 1]) {
            child++;
        }
        if (temp >= array[child]) {
            break;
        } else {
            array[parent] = array[child];
            parent = child;
            child = 2 * parent + 1;
        }
    }
    array[parent] = temp;
}

时间复杂度为O(nlogn),不稳定。

示例说明

例如,我们有一个待排序的数组:

int[] array = new int[]{4, 9, 8, 3, 5, 1, 6, 2, 7};

如果我们希望对这个数组进行归并排序,我们可以使用以下代码:

MergeSort.mergeSort(array, 0, array.length - 1);

最终得到的有序数组如下:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

再例如,如果我们希望对一个包含大量元素的数组进行排序,我们可以选择堆排序算法,通过以下代码实现:

int[] array = new int[100000];
for (int i = 0; i < 100000; i++) {
    array[i] = (int) (Math.random() * 100000);
}
HeapSort.heapSort(array);

以上代码将产生包含100000个随机元素的数组,然后使用堆排序算法进行排序。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java各种排序算法汇总(冒泡,选择,归并,希尔及堆排序等) - Python技术站

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

相关文章

  • 详解Spring Boot Web项目之参数绑定

    下面是“详解Spring Boot Web项目之参数绑定”的完整攻略。 什么是参数绑定? 在Web开发过程中,我们经常需要将用户通过表单提交的数据绑定到控制器方法参数上,以方便后续业务逻辑的处理。参数绑定是指Spring将请求参数的值绑定到指定的控制器方法的参数上。 Spring Boot中的参数绑定 Spring Boot提供了简单易用的参数绑定机制,使用…

    Java 2023年5月19日
    00
  • 基于module-info.class的问题

    “基于module-info.class的问题” 在Java 9之前是不存在的。 Java SE 9中引入了模块化系统,它引入了一个新的文件模块描述符module-info.java。module-info.java包含有关模块的信息,包括模块依赖关系,公共包导入等。在模块化系统中,其他类需要使用Java模块,需要module-info.java中导入的包。…

    Java 2023年5月19日
    00
  • 关于Java中方法重载和方法重写

    方法重写是子类继承父类(默认继承Object类)后覆盖父类的方法 需要保证同名 同参 同返回值 且访问权限范围不能缩小(public>protected>default>private) public class Father{ public int method(){ return -1; } } class Son extends Fa…

    Java 2023年4月22日
    00
  • 解决struts2 拦截器修改request的parameters参数失败的问题

    首先,我们需要了解为什么拦截器无法修改参数。这是因为Struts 2在请求参数提交后,将参数作为只读值放到了ValueStack中,而拦截器只能获取到ValueStack中原有的参数值,而不能修改ValueStack中的参数。 要解决这个问题,我们需要使用Struts2提供的params拦截器。这个拦截器会在Action执行之前拦截请求,并将请求参数转换为可…

    Java 2023年5月20日
    00
  • Java多线程工具CompletableFuture的使用教程

    Java多线程工具CompletableFuture的使用教程 介绍 在 Java 1.8 版本中,加入了 CompletableFuture 类,它是一种新的 Future 类型,用于异步计算任务的完成(无需调用线程池提供的线程)。CompletableFuture 可以将异步操作串行化,也可以将多个异步操作组合和并为一个结果。本文将全面介绍 Comple…

    Java 2023年5月18日
    00
  • 详解MyBatis Generator自动创建代码(dao,mapping,poji)

    下面我将详细讲解MyBatis Generator自动创建代码的完整攻略,包括使用步骤和示例说明。 MyBatis Generator是什么 MyBatis Generator是MyBatis框架家族中的一员,是一款自动生成MyBatis持久层代码(Mapper接口和Mapper XML文件)的工具。它是根据数据库表结构自动生成对应的JavaBean、Map…

    Java 2023年6月1日
    00
  • SpringBoot深入理解之内置web容器及配置的总结

    Spring Boot深入理解之内置Web容器及配置的总结 什么是Spring Boot内置Web容器 Spring Boot是一种轻量级Java开发框架,它简化了Spring应用程序的构建和部署过程。它支持内置Web容器,如Tomcat、Jetty和Undertow。这意味着您可以直接使用可执行Jar文件启动Spring应用程序而无需外部Web服务器。 S…

    Java 2023年5月15日
    00
  • 浅谈java中math类中三种取整函数的区别

    下面是我对题目“浅谈java中math类中三种取整函数的区别”的详细攻略: 1. 引言 Java中的Math类提供了很多用于数值计算的方法。本文将重点讲解Math类中的三种取整函数的区别:round、ceil和floor。这三个函数的共同点是,它们都返回近似值且返回类型为整数。它们的不同之处将在下文中进行详细比较。 2. Math类中的三种取整函数 2.1 …

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