Java 数据结构之堆的概念与应用

Java 数据结构之堆的概念与应用

堆的概念

在计算机科学中,堆(Heap)是一种特殊的数据结构,是一棵树,每个父节点的键值都小于其子节点的键值,这样的堆成为小根堆(Min Heap),反之成为大根堆(Max Heap)。在堆中没有父子关系的节点之间也没有其他约束关系。常见的堆有二叉堆、斐波那契堆等。

对于小顶堆,任意节点的键值都小于或等于其子节点的键值,根节点的键值最小,可以用于实现优先队列(Priority Queue),时间复杂度为logN。

堆的应用

二叉堆

二叉堆是堆的一种常见而简单的实现,它可以用来实现堆栈(Heap Stack)和优先队列(Heap Priority Queue)。二叉堆分为最大堆和最小堆两种。

最大堆

在最大堆中,任何一个父节点的值都大于或等于其左右子节点的值,即根节点的值最大。

Java中的PriorityQueue就是一种基于最大堆的实现,可以通过以下代码创建:

PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(Collections.reverseOrder());

最小堆

在最小堆中,任何一个父节点的值都小于或等于其左右子节点的值,即根节点的值最小。

可以通过以下代码创建:

PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();

堆排序

堆排序是一种原地排序算法,基于二叉堆实现。具体步骤如下:

  1. 将要排序的数组构造成二叉堆
  2. 将堆顶元素与堆底元素交换
  3. 重新构造二叉堆,并重复步骤2,直到整个数组排序完成

Java实现代码如下:

public static void heapSort(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--) {
        int temp = arr[0];
        arr[0] = arr[i];
        arr[i] = temp;
        heapify(arr, i, 0);
    }
}

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) {
        int temp = arr[i];
        arr[i] = arr[largest];
        arr[largest] = temp;
        heapify(arr, n, largest);
    }
}

示例说明

下面通过一个示例,说明堆的应用和使用:

假设有一个数组,我们需要找到其中第K大的数,可以通过构造一个小根堆,遍历数组将元素加入到堆中,并控制堆的大小不超过K,遍历完成后堆顶元素即为第K大的数。

代码如下:

public static int findKthLargest(int[] nums, int k) {
    PriorityQueue<Integer> pQueue = new PriorityQueue<Integer>();
    for(int i=0; i<nums.length; i++) {
        pQueue.offer(nums[i]);
        if(pQueue.size() > k) {
            pQueue.poll();
        }
    }
    return pQueue.peek();
}

另一个示例是使用堆排序对数组进行排序,代码如下:

int[] arr = new int[]{7, 3, 5, 2, 6, 1, 4};
heapSort(arr);
System.out.println(Arrays.toString(arr));

输出结果为[1, 2, 3, 4, 5, 6, 7]

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 数据结构之堆的概念与应用 - Python技术站

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

相关文章

  • 详解Java如何实现加密或者解密PDF文档

    让我来详细讲解Java如何实现加密或者解密PDF文档的完整攻略。 一、PDF加密或解密的基本原理 在讲解如何实现PDF加密或解密之前,先来了解一下PDF加密或解密的基本原理。 PDF加密是通过对PDF文档进行加密处理,在文档中添加一些限制来保护PDF文档的安全性。PDF加密主要包括以下方式: 对PDF文档全文进行加密,需要输入密码才能查看; 对PDF文档的部…

    Java 2023年5月26日
    00
  • Spring Boot集成Quartz注入Spring管理的类的方法

    下面详细讲解如何使用Spring Boot集成Quartz并注入Spring管理的类。 准备工作 首先,我们需要引入相关依赖。在 pom.xml 中加入以下依赖: <!– Quartz –> <dependency> <groupId>org.quartz-scheduler</groupId> <a…

    Java 2023年5月31日
    00
  • 基于java实现简单的银行管理系统

    我们来详细讲解“基于Java实现简单的银行管理系统”的完整攻略。 1. 确定需求和设计整体架构 在开发任何一种软件系统之前,我们都需要先明确需求,明确需要实现哪些功能和用户需求。在之后的设计过程中,我们需要设计整体的架构。 在本项目中,我们可以按如下的步骤进行: 分析整个系统,确定需要的基本功能和用户需求(例如:存、取、转账、查询余额等)。 设计整体的系统架…

    Java 2023年5月18日
    00
  • Spring异常实现统一处理的方法

    下面我将详细讲解Spring异常实现统一处理的方法。 背景 在Spring应用程序中,系统可能会出现各种异常,如数据库连接异常、空指针异常等等。这些异常可能会导致应用程序崩溃或无法正常运行,对于程序员,处理这些异常非常重要。而在处理异常时,统一处理异常是一种最佳的方法。 实现步骤 第一步:全局异常处理类 编写一个全局异常处理类,该类应该用@Controlle…

    Java 2023年5月20日
    00
  • Java编程实现的二维数组转置功能示例

    下面我来详细讲解“Java编程实现的二维数组转置功能示例”的完整攻略。 什么是二维数组转置? 二维数组转置就是将原本按行存储的二维数组,按列存储重新排列的过程。例如,原先的二维数组表示为: 1 2 3 4 5 6 经过转置之后,变成了: 1 4 2 5 3 6 实现二维数组转置的方法 实现二维数组转置的方法有很多种,本篇文章主要介绍两种方式: 方法一:使用一…

    Java 2023年5月26日
    00
  • Java中的异常处理机制是什么?

    Java中的异常处理机制是通过try-catch语句块和throw抛出异常语句实现的。以下是Java中异常处理机制的详细步骤: 1. 什么是异常 在编写程序时,不可避免遇到一些非预期的错误,这些错误被成为异常。Java中的异常是一种对象,它用来信号某个方法出现了错误,有关这种错误的信息被封装在异常对象中并传递给调用该方法的程序。 2. 异常分类 Java中的…

    Java 2023年4月27日
    00
  • 鼠标焦点离开文本框时验证的js代码

    当用户在网页中填写表单时,我们常常需要验证用户输入的数据是否合法。而当用户在输入框输入完内容后,离开这个输入框,我们需要验证这个输入框中的内容是否符合我们的要求,这时候我们就需要使用JavaScript代码来验证用户的输入。以下是实现鼠标焦点离开文本框时验证的js代码的完整攻略。 1. 绑定事件 我们需要先为输入框绑定一个事件,当输入框失去焦点时触发这个事件…

    Java 2023年6月15日
    00
  • 如何在Android studio导入jdk9及以上版本中依赖包,如’rt.jar’,’ dt.jar’等

    1、如何获取jdk9及以上版本中依赖包,如’rt.jar’,’ dt.jar’等 ​ 在jdk9及后续版本中,jdk开始使用模块化规则,实现更好的封装和定义良好的接口,近一步加强了java的自由度,开发者可以定制化SDK ​ 包括rt.jar在内的依赖均已移除,以模块化形式更高效的存诸在 JAVA_HOME/jmods目录下 ​ 如果需要可以用命令进行抽取,…

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