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日

相关文章

  • 快速定位Java 内存OOM的问题

    快速定位Java 内存OOM的问题完整攻略 什么是Java OOM? Java Out Of Memory(简称Java OOM)指的是Java虚拟机向操作系统申请内存失败,导致异常终止程序运行的问题。原因可能是Java堆内存不足,也可能是永久代、元空间等内在资源耗尽。 快速定位Java OOM的过程 1. 分析异常数据 当Java OOM产生时,JVM会把…

    Java 2023年5月27日
    00
  • Spring框架的JdbcTemplate使用

    Spring框架的JdbcTemplate是一种轻量级的Java数据访问框架,可以让Java开发人员更方便地使用数据库,同时提供了非常好的性能和灵活性。 以下是使用Spring框架的JdbcTemplate的完整攻略: 1. 添加对JdbcTemplate的依赖 在项目中pom.xml文件中添加以下maven依赖,以使用JdbcTemplate: <d…

    Java 2023年5月20日
    00
  • Java Spring 声明式事务详解

    Java Spring 是一个非常流行的开源框架,可以用来构建企业级应用程序。Spring 内置了事务管理器,提供了声明式事务的支持,让我们能够更加方便地管理事务。本篇文章将着重讲解 Java Spring 声明式事务的完整攻略。 什么是声明式事务 声明式事务是基于 Spring AOP 的一种事务管理方式,它通过对业务方法进行拦截和代理,从而实现自动管理事…

    Java 2023年5月20日
    00
  • Java访问者模式实现优雅的对象结构处理

    Java访问者模式实现优雅的对象结构处理 什么是访问者模式 访问者模式(Visitor Pattern)是一种行为型设计模式,它可以用于在不改变对象结构的前提下,对对象的元素进行新的操作。它将算法与对象结构分离开来,能够在不修改已有的类结构的情况下,向现有对象结构添加新的操作。 访问者模式的角色 访问者模式中包含如下角色: 抽象访问者(Visitor):为对…

    Java 2023年5月26日
    00
  • fastjson对JSONObject中的指定字段重新赋值的实现

    要对JSONObject中的指定字段重新赋值,可以使用FastJSON提供的API。具体实现过程如下: 首先,我们需要将JSONObject转化为Java对象。可以使用FastJSON提供的parseObject方法,将JSONObject字符串转化成Java对象,并指定Java对象的Class类型。如下所示: String jsonString = &qu…

    Java 2023年5月26日
    00
  • 详解SpringBoot2 使用Spring Session集群

    详解SpringBoot2 使用Spring Session集群攻略 什么是Spring Session Spring Session是一个支持在不同Web容器之间共享Session数据的项目。 Spring Session的集群 在集群环境下,我们需要使用Spring Session来共享Session数据。具体实现方式如下: 引入Spring Sessi…

    Java 2023年5月19日
    00
  • Java多线程之条件对象Condition

    Java多线程中的条件对象Condition是在java.util.concurrent.locks包下的,它和synchronized关键字一样,可以协调线程的执行顺序和通信,不过其功能更为强大,可用于等待条件、通知单个线程和通知所有等待线程。 一、条件对象Condition的基本用法 1. 创建Condition对象 在使用Condition对象前,需要…

    Java 2023年5月19日
    00
  • Groovy动态语言使用教程简介

    Groovy动态语言使用教程简介 什么是Groovy动态语言 Groovy是一种基于JVM的动态语言,它可以与Java语言无缝集成并且具备很多Java语言的特性。Groovy动态语言的主要特点是它支持运行时的元编程和动态方法调用,使得程序员可以更加灵活地开发项目并提高开发效率。 Groovy的安装和配置 在使用Groovy之前,需要安装和配置相应的环境。以下…

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