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日

相关文章

  • java 反射机制详解及实例代码

    Java反射机制详解 Java反射机制是指在运行时使用Reflection API动态获取类信息、构造对象、调用方法、访问属性等。反射机制在框架开发、ORM映射、动态代理、JavaBean工具、JUnit单元测试等领域有着广泛的应用。 反射机制的特性 Java反射机制具有以下特性: 运行时类型信息:反射机制可以获取类的各种信息,例如类名、父类、接口、方法、属…

    Java 2023年5月23日
    00
  • MyBatis入门实例教程之创建一个简单的程序

    首先我们需要明确一下MyBatis的基础知识。MyBatis是一个持久层框架,可以与关系型数据库进行交互。在使用MyBatis时,我们需要进行以下三步操作: 配置数据源:需要在MyBatis的配置文件中配置数据库的连接信息。 编写Mapper文件:Mapper文件是MyBatis的核心,用于描述SQL语句以及与Java对象之间的映射关系。 执行SQL语句:通…

    Java 2023年5月20日
    00
  • 详解Java数组的一维和二维讲解和内存显示图

    详解Java数组的一维和二维讲解和内存显示图 一维数组 一维数组是一种最简单的数组,它是一组相同类型的变量的有序集合。数组中的每个变量是一个元素,每个元素都有一个唯一的下标。 声明一维数组 声明一维数组的语法如下: type[] arrayName; 其中,type可以是Java中任何一种数据类型。下面是一个声明整数数组的例子: int[] numbers;…

    Java 2023年5月26日
    00
  • JavaIO BufferedReader和BufferedWriter使用及说明

    JavaIO BufferedReader和BufferedWriter使用及说明 在Java中,读写文件是非常频繁的操作。BufferedReader和BufferedWriter是常用的文件读写工具类。本文将详细介绍这两个工具类的使用方法及说明。 BufferedReader BufferedReader是一个用来读取字符流的缓冲区。它以一个字符输入流作…

    Java 2023年5月20日
    00
  • 详解APP微信支付(java后台_统一下单和回调)

    详解APP微信支付(java后台_统一下单和回调) 一、前言 在移动APP中,使用微信支付功能是非常常见的需求,而且使用微信支付也是比较方便和快捷的。本文将详细介绍如何在Java后台中实现微信支付的功能。主要包括两部分:统一下单和回调。本文介绍的支付接口都是官方的API接口,并采用了最新的V3版本。 二、统一下单 下单接口是微信支付功能的核心,接口名称为:h…

    Java 2023年5月27日
    00
  • java线程间通讯的一些方法总结

    关于“Java线程间通讯的一些方法总结”的攻略,我从以下几点进行详细讲解: 一、线程间通讯的基本概念 1. 定义 线程间通讯指的是多个线程之间相互发送信息(数据)的行为。每个线程需要知道其他线程的存在以及如何与其他线程进行通信。 2. 通讯方法 实现线程间通讯的方法有以下几种: 共享变量 管道通信 消息队列 信号量 事件(条件) 二、共享变量的线程间通讯 1…

    Java 2023年5月26日
    00
  • Spring Data Jpa 自动生成表结构的方法示例

    首先,我们需要先了解Spring Data Jpa自动生成表结构的方法。Spring Data Jpa是Spring框架中的一个重要组成部分,它提供了一种方便快捷的方式来管理和操作数据库中的数据。 Spring Data Jpa可以自动生成表结构,这样就不需要手动编写SQL语句来创建表了。具体的步骤如下: 配置数据源 在你的Spring应用程序中,你需要首先…

    Java 2023年5月20日
    00
  • hibernate查询缓存详细分析

    Hibernate查询缓存详细分析 Hibernate是一个开源的持久性框架,支持使用注解、XML文件或者API访问数据库。Hibernate查询缓存可以显著提高应用程序的执行效率和性能。本文将分析Hibernate查询缓存并提供一些示例说明。 什么是Hibernate查询缓存 Hibernate查询缓存是指在缓存中缓存查询结果,避免重复执行相同的SQL语句…

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