Java代码为例讲解堆的性质和基本操作以及排序方法

Java代码为例讲解堆的性质和基本操作以及排序方法

什么是堆?

堆(Heap)是一种基于二叉树的数据结构,常用于排序和优先级队列中。堆又分为大根堆和小根堆,大根堆满足任意节点的值都不大于其父节点的值,小根堆则相反。这里我们以大根堆为例。

堆的基本操作

插入元素

堆的插入操作是往堆中添加新值并保证堆的性质不变。具体实现如下:

public void insert(int value) {
    if (size == maxsize)
        return;
    heap[size] = value;
    int current = size;
    while (heap[current] > heap[parent(current)]) {
        swap(current, parent(current));
        current = parent(current);
    }
    size++;
}

其中,size为当前堆中元素数量,maxsize为堆的最大容量,heap为堆的数组,parent(current)为当前节点的父节点,swap(current, parent(current))为交换当前节点和父节点。

删除元素

堆的删除操作是删除堆的根节点并保持堆的性质。具体实现如下:

public int delete() {
    int popped = heap[0];
    heap[0] = heap[--size];
    heapify(0);
    return popped;
}

public void heapify(int index) {
    int largest = index;
    int left = leftChild(index);
    int right = rightChild(index);
    if (left < size && heap[left] > heap[largest])
        largest = left;
    if (right < size && heap[right] > heap[largest])
        largest = right;
    if (largest != index) {
        swap(index, largest);
        heapify(largest);
    }
}

其中,popped为删除的元素,leftChild(index)为当前节点的左侧子节点,rightChild(index)为当前节点的右侧子节点。

建立堆

如果给定的无序数组需要排序,可以先将其构建成一个堆再进行排序。建立堆的过程称为堆化。具体实现如下:

public void buildHeap(int[] arr) {
    if (arr.length > maxsize)
        return;
    size = arr.length;
    heap = Arrays.copyOf(arr, maxsize);
    for (int i = (size - 2) / 2; i >= 0; i--) {
        heapify(i);
    }
}

其中,arr为给定的数组,Arrays.copyOf(arr, maxsize)为将arr数组复制到大小为maxsize的heap数组中,(size - 2) / 2为最后一个非叶子节点的下标。

排序方法

堆排序

堆排序以大根堆为例,其基本思路是先将待排序序列构建成一个大根堆,再不断将堆的根节点和堆的最后一个非空节点交换,然后将堆的大小减1,再进行调整,直到堆的大小为1为止。

具体实现如下:

public void heapSort(int[] arr) {
    buildHeap(arr);
    for (int i = size-1; i > 0; i--) {
        swap(0, i);
        size--;
        heapify(0);
    }
}

其中,buildHeap(arr)为构建堆,swap(0, i)为交换第一个元素(堆的根节点)和第i个元素。

示例1:

假设给定一个无序序列[4, 10, 3, 5, 1, 8, 9],进行堆排序后的结果应该是[1, 3, 4, 5, 8, 9, 10]。

int[] arr = {4, 10, 3, 5, 1, 8, 9};
HeapSort hs = new HeapSort();
hs.heapSort(arr);
System.out.println(Arrays.toString(arr));

输出结果为[1, 3, 4, 5, 8, 9, 10]。

示例2:

假设给定一个无序序列[6, 3, 7, 8, 1, 4, 5, 9, 2],求第K大的数,这里以K=2为例。

int[] arr = {6, 3, 7, 8, 1, 4, 5, 9, 2};
HeapSort hs = new HeapSort();
hs.buildHeap(arr);
for (int i = 0; i < 2; i++) {
    hs.delete();
}
System.out.println(hs.delete());

输出结果为8,即第2大的数为8。

总结

堆是一种基于二叉树的数据结构,常用于排序和优先级队列中。堆的基本操作包括插入元素、删除元素和建立堆,其中建立堆是进行堆排序的先决条件。堆排序的基本思路是先将待排序序列构建成一个大根堆,再不断将堆的根节点和堆的最后一个非空节点交换,然后将堆的大小减1,再进行调整,直到堆的大小为1为止。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java代码为例讲解堆的性质和基本操作以及排序方法 - Python技术站

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

相关文章

  • SpringData JPA中@OneToMany和@ManyToOne的用法详解

    下面我将详细讲解“SpringData JPA中@OneToMany和@ManyToOne的用法详解”的完整攻略。 什么是@OneToMany和@ManyToOne 在关系型数据库中,一个对象与另一个对象之间存在着不同的关系,如一对一、一对多、多对一、多对多等。而在Java中,对象之间的关系可以用多种方式来表示和映射到数据库中。Spring Data JPA…

    Java 2023年5月20日
    00
  • JAVA验证码工具实例代码

    JAVA验证码工具实例代码完整攻略 验证码是一种用来区分人类和计算机的一种技术,通常应用于网站注册、登录等场景中。在JAVA中,我们可以借助一些工具来实现验证码的生成和验证,下面我们就来了解一下。 验证码工具的选择 JAVA中有很多开源的验证码工具,常见的有Kaptcha、JCaptcha等。这里我们介绍一种比较常用的JAVA验证码工具——JCaptcha。…

    Java 2023年6月15日
    00
  • 在IDEA中创建跑得起来的Springboot项目

    让我来详细讲解如何在IntelliJ IDEA中创建跑得起来的Spring Boot项目。 1. 准备工作 在开始创建Spring Boot项目之前,我们需要确保电脑上已经安装好以下两个软件:- JDK 1.8或更高版本- IntelliJ IDEA 2. 创建Spring Boot项目 现在我们来开始创建Spring Boot项目。 2.1 打开Intel…

    Java 2023年5月19日
    00
  • SpringBoot监控Tomcat活动线程数来判断是否完成请求处理方式

    要实现Spring Boot监控Tomcat线程数并判断是否请求处理完成可以采用以下步骤: 1. 添加actuator依赖 要使用Spring Boot提供的监控功能,需要添加actuator依赖,具体方法是在项目的pom.xml文件中添加以下代码: <dependency> <groupId>org.springframework.…

    Java 2023年5月19日
    00
  • 基于Java创建一个订单类代码实例

    以下是基于Java创建一个订单类的完整攻略过程: 1. 定义订单类 在创建订单类之前,需要先明确订单类需要存储哪些信息,例如订单编号、订单创建时间、订单金额等等,再根据这些信息定义订单类的属性。同时,还需要定义订单类的基本行为,例如添加商品到订单、计算订单总金额等等,并将这些功能定义为订单类的方法。 public class Order { private …

    Java 2023年5月23日
    00
  • 使用Spring Boot+MyBatis框架做查询操作的示例代码

    接下来我将为您分享使用Spring Boot+MyBatis框架进行查询操作的攻略。 1. 环境搭建 首先,需要配置好开发环境,包括Java环境和IDE工具。具体操作可以参考相关网上教程。 然后需要添加Spring Boot和MyBatis的依赖,这里以Maven为例,可以在pom.xml文件中添加以下代码实现依赖的导入: <dependencies&…

    Java 2023年5月20日
    00
  • logback过滤部分日志输出的操作

    当我们在开发、调试和运行程序时,经常会遇到需要限制部分日志的输出情况。这时候就需要使用logback的过滤器来实现。 在logback中,我们可以通过使用标签来定义过滤器。logback提供了多种过滤器,如LevelFilter、ThresholdFilter、AndFilter、OrFilter、TurboFilter等,通过组合这些过滤器,实现对日志输出…

    Java 2023年5月20日
    00
  • Spring Security 表单登录功能的实现方法

    下面为您讲解Spring Security表单登录功能的实现方法: 1. 配置Spring Security 在pom文件中添加依赖: <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security…

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