JAVA堆排序算法的讲解

JAVA堆排序算法的讲解

算法简介

堆排序(Heap Sort)是一种选择排序,它的主要思想是将待排序序列构建成一个大顶堆或小顶堆,然后将堆顶元素与最后一个元素交换位置,再对剩余 n - 1 个元素进行同样的操作,依次类推,直到整个序列有序。

堆排序的时间复杂度为 O(nlogn),是一种比较高效的排序算法。

算法步骤

  1. 对待排序的序列进行堆的构建,构建出一个大顶堆或小顶堆;
  2. 构建出堆后,堆顶元素一定是最大或最小的元素,将其与序列的最后一个元素进行交换;
  3. 排除掉已经排好序的最后一个元素,对剩余元素重新构建堆,重复步骤2和3,直到所有元素都已经排好序。

代码实现

JAVA 代码实现

/**
 * 堆排序算法
 * 时间复杂度:O(nlogn)
 */
public class HeapSort {

    public static void sort(int[] arr) {
        int n = arr.length;

        // 构建大顶堆,从最后一个非叶子节点开始向下调整
        for (int i = n / 2 - 1; i >= 0; i--)
            heapify(arr, n, i);

        // 将堆顶元素与序列最后一个元素交换位置,然后对剩余元素重新构建堆
        for (int i = n - 1; i >= 0; i--) {
            swap(arr, 0, i);
            heapify(arr, i, 0);
        }
    }

    /**
     * 将以i为根节点的子树调整成大顶堆
     * @param arr 数组
     * @param n 数组长度
     * @param i 根节点位置
     */
    private static void heapify(int[] arr, int n, int i) {
        int largest = i; // 根节点
        int left = 2 * i + 1; // 左子节点
        int right = 2 * i + 2; // 右子节点

        // 找到最大的节点
        if (left < n && arr[left] > arr[largest])
            largest = left;
        if (right < n && arr[right] > arr[largest])
            largest = right;

        // 如果最大节点不是根节点,那么把最大节点与根节点交换,然后继续向下递归调整
        if (largest != i) {
            swap(arr, i, largest);
            heapify(arr, n, largest);
        }
    }

    /**
     * 交换数组中的两个元素
     * @param arr 数组
     * @param i 元素1的位置
     * @param j 元素2的位置
     */
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

Python 代码实现

def heap_sort(arr):
    n = len(arr)

    # 构建大顶堆,从最后一个非叶子节点开始向下调整
    for i in range(n // 2 - 1, -1, -1):
        heapify(arr, n, i)

    # 将堆顶元素与序列最后一个元素交换位置,然后对剩余元素重新构建堆
    for i in range(n - 1, 0, -1):
        arr[0], arr[i] = arr[i], arr[0]
        heapify(arr, i, 0)

def heapify(arr, n, i):
    largest = i # 根节点
    left = 2 * i + 1 # 左子节点
    right = 2 * i + 2 # 右子节点

    # 找到最大的节点
    if left < n and arr[left] > arr[largest]:
        largest = left
    if right < n and arr[right] > arr[largest]:
        largest = right

    # 如果最大节点不是根节点,那么把最大节点与根节点交换,然后继续向下递归调整
    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i]
        heapify(arr, n, largest)

示例

示例1

排序前的数组:[5, 3, 8, 4, 7, 2, 6, 1]

排序后的数组:[1, 2, 3, 4, 5, 6, 7, 8]

示例2

排序前的数组:[99, 0, 33, 46, 12, 78, 21, 5]

排序后的数组:[0, 5, 12, 21, 33, 46, 78, 99]

总结

堆排序算法是一种高效的排序算法,适用于大规模数据的排序。它通过构建大顶堆或小顶堆,实现了对序列的快速排序。堆排序可以通过数组实现,也可以通过树实现。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JAVA堆排序算法的讲解 - Python技术站

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

相关文章

  • Windows下Apache+Tomcat7负载均衡配置方法详解

    Windows下Apache+Tomcat7负载均衡配置方法详解 在Windows系统中使用Apache和Tomcat实现负载均衡是常见的配置方法之一。下面将详细讲解如何在Windows中实现Apache和Tomcat7的负载均衡配置。 步骤一:安装Apache和Tomcat7 首先需要在Windows系统中安装Apache和Tomcat7。可以从Apach…

    Java 2023年5月19日
    00
  • Java如何实现判断并输出文件大小

    下面我将详细讲解 Java 如何实现判断并输出文件大小的完整攻略: 1. 获取文件大小方法 Java 中可以使用 File 类的 length() 方法来获取文件的大小,该方法返回文件的长度,以字节为单位。代码示例如下: import java.io.File; public class FileSizeDemo { public static void m…

    Java 2023年5月20日
    00
  • Java中Mybatis分页查询的四种传参方式

    前言 在使用 Mybatis 进行分页查询时,我们需要传递分页参数给 Mybatis,以告知查询的起始位置和数量。这篇文章将会详细介绍 Java 中 Mybatis 分页查询的四种传参方式。 前置条件 在介绍 Mybatis 分页查询的传参方式之前,需要先完成如下准备工作: 导入 Mybatis 和 Mybatis-spring 的 jar 包 编写 Myb…

    Java 2023年5月20日
    00
  • springboot 配置DRUID数据源的方法实例分析

    SpringBoot配置Druid数据源的方法实例分析 在SpringBoot中,我们可以使用Druid数据源连接数据库,本文将详细讲解如何在SpringBoot中配置Druid数据源的方法。 引入Druid依赖 在pom.xml文件中,添加Druid依赖: <dependency> <groupId>com.alibaba</…

    Java 2023年5月20日
    00
  • Springboot项目实现Mysql多数据源切换的完整实例

    下面是完整的攻略说明: 1. 前言 在实际开发中,一个服务可能需要涉及多个数据库,为了不同的业务之间数据互不干扰,我们需要对不同的业务使用不同的数据库。Spring Boot提供了良好的支持,使得我们很容易地实现多数据源切换。本文将介绍如何使用Spring Boot来实现Mysql多数据源切换。 2. 配置多数据源 在Spring Boot中,要使用多数据源…

    Java 2023年5月20日
    00
  • java IO流文件的读写具体实例

    关于Java IO流文件的读写,我可以在本文中为您提供详细的攻略。 什么是Java IO流? 首先,我们需要了解一下Java IO流是什么。简单来说,IO流就是Java中用于读写数据的机制。在Java中,IO流一般用于文件的读写,网络数据的传输等场景。 Java IO流操作文件 接下来,我们来看一下Java中如何读写文件。Java中提供了多种方式进行文件的读…

    Java 2023年5月20日
    00
  • 关于SpringBoot创建存储令牌的媒介类和过滤器的问题

    Spring Boot是一个流行的Java框架,可以用于快速开发Web应用程序。在Web应用程序中,通常需要使用token进行身份验证和授权,因此创建和存储令牌是非常重要的。本文将介绍如何使用Spring Boot创建媒介类和过滤器来存储和验证token并解决与存储令牌有关的问题。 创建TokenStorage媒介类 TokenStorage是一个媒介类,用…

    Java 2023年5月19日
    00
  • Dockerfile制作官方Tomcat镜像及镜像使用详解

    Dockerfile制作官方Tomcat镜像及镜像使用详解,需要分为两个部分来讲解:制作Tomcat镜像和使用Tomcat镜像。下面我将分别进行详细讲解。 制作Tomcat镜像 制作Tomcat镜像需要用到Dockerfile文件,具体步骤如下: 步骤一:选择合适的基础镜像 由于Tomcat是基于Java开发的应用服务器,因此可以选择Java镜像作为基础镜像…

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