Java 中的堆实现2025年8月4日 | 阅读 16 分钟 在 Java 中,堆是一种特殊的数据结构,其中根节点或父节点与左右子节点进行比较,并根据顺序排列。假设 x 是一个根节点,y 是一个子节点,属性key(x) <= key(y) 会生成最小堆,并且这种关系被称为“堆属性”。 根据父节点和子节点的顺序,堆可以分为两种形式,即最小堆和最大堆。让我们一个一个地理解它们,并在 Java 中实现代码。 堆的操作插入:将新元素添加到堆(数组)的末尾,然后“向上堆化”,通过将添加的元素与其父节点进行比较并根据需要进行交换,直到找到正确的位置,以维护堆属性。 删除:删除根元素(最小堆的最小值,最大堆的最大值),用堆中的最后一个元素替换它,然后“向下堆化”,通过将新的根与其子节点进行比较并根据需要进行交换,直到找到正确的位置。 堆化:调整堆以维护堆属性。在向上堆化中,将新添加的元素与其父节点进行比较,并在需要时进行交换。在向下堆化中,将根元素与其子节点进行比较,并在需要时进行交换。此过程确保堆仍然是有效的最小堆或最大堆。 最小堆最小堆是一种特殊的堆数据结构,它本身是一个完全二叉树。最小堆具有以下属性
我们可以在最小堆中执行以下三个操作 insertNode()我们可以通过将新键添加到树的末尾来在最小堆中执行插入。如果插入键的值小于其父节点,我们必须向上遍历键以满足堆属性。插入过程需要 O(log n) 时间。 extractMin()这是最重要的操作之一,我们通过它来删除最小值节点,即堆的根节点。删除根节点后,我们必须确保堆属性得到维护。extractMin() 操作需要 O(Logn) 时间来从堆中删除最小值。 getMin()getMin() 操作用于以 O(1) 时间获取堆的根节点,即最小值。 示例 ![]() 最小堆算法 MinHeapJavaImplementation.java 输出 ![]() 使用数组最小堆是一种二叉树,其中父节点的值总是小于其子节点的值,从而确保最小值位于根节点。使用数组在 Java 中实现最小堆可以通过简单的索引算术来实现高效的插入、删除和堆化。这种结构非常适合需要快速访问最小元素的应用程序,例如优先队列。 文件名:RefactoredMinHeap.java 输出 The Min Heap is: [3, 13, 7, 16, 21, 12, 9] Parent : 3 Left : 13 Right : 7 Parent : 13 Left : 16 Right : 21 Parent : 7 Left : 12 Right : 9 The Min Value is: 3 The Min Heap is: [7, 13, 9, 16, 21, 12, 9] Parent : 7 Left : 13 Right : 9 Parent : 13 Left : 16 Right : 21 Parent : 9 Left : 12 最大堆最大堆是另一种特殊的堆数据结构,它在 Java 中也是一个完全二叉树。最大堆具有以下属性
我们可以在最大堆中执行以下三个操作 insertNode()我们可以通过将新键添加到树的末尾来在最大堆中执行插入。如果插入键的值大于其父节点,我们必须向上遍历键以满足堆属性。插入过程需要 O(log n) 时间。 extractMax()这是最重要的操作之一,我们通过它来删除最大值节点,即堆的根节点。删除根节点后,我们必须确保堆属性得到维护。extractMax() 操作需要 O(Log n) 时间来从堆中删除最大值。 getMax()getMax() 操作用于以 O(1) 时间获取堆的根节点,即最大值。 示例 ![]() 最小堆算法 MaxHeapJavaImplementation.java 输出 ![]() 使用 Collections.reverseOrder() 方法通过库函数Java 中的 Collections.reverseOrder() 方法是一个强大的实用程序,用于反转集合中元素的自然顺序。此方法返回一个比较器,该比较器对实现 Comparable 接口的对象集合施加与自然顺序相反的顺序。通过利用此方法,开发人员可以轻松地将最小堆转换为最大堆,反转已排序列表的顺序,或调整优先队列中元素的优先级。 文件名:MaxHeapDemo.java 输出 Head value using peek function:400 The queue elements: 400 30 20 10 After removing an element with poll function: 30 10 20 After removing 30 with remove function: 20 10 Priority queue contains 20 or not?: true Values in array: Value: 20 Value: 10 堆的应用优先队列:堆通常用于实现优先队列,其中优先级最高的元素首先被提取。这在任务调度、中断处理和事件处理等应用程序中至关重要。 排序算法:堆排序是一种基于比较的排序算法,它依赖于堆数据结构。它的时间复杂度为 O(n log n),因此对于对大型数据集进行排序非常有效。 图算法:堆在 Dijkstra 的最短路径算法、Prim 的最小生成树算法和 A* 搜索算法等图算法中是不可或缺的。 文件压缩:堆在霍夫曼编码等数据压缩技术中起着至关重要的作用。在这里,一个优先队列(通常实现为最小堆)用于构建霍夫曼树。 动态规划:堆在动态规划算法中使用,特别是在贪心算法中,其中元素根据其优先级进行处理。 医疗应用:在医疗环境中,堆用于管理患者信息,包括生命体征、治疗和检查结果,这些信息根据其危急程度或紧急程度进行管理。 外部排序:堆用于外部排序算法,以有效地对超出内存容量的大型数据集进行排序。数据块使用优先队列进行处理。 负载均衡:堆应用于负载均衡算法,以在服务器之间分配任务或请求。任务通常根据其优先级或负载进行处理。 在线算法:堆在处理实时到达数据的在线算法中使用,例如在推荐系统、事件处理和流数据管理中。 金融应用:堆用于股票市场分析和算法交易等金融应用程序,它们根据优先级管理和处理股票数据。 堆的优点高效的插入和删除:堆结构支持高效的元素插入和删除。当插入新元素时,它最初放在堆的末尾,然后使用堆化操作移动到其正确的位置。同样,当删除元素时,它被堆中的最后一个元素替换,并使用堆化操作重新组织堆。 高效的优先队列实现:堆通常用于实现优先队列,其中最高优先级的元素始终位于堆的顶部。这允许对最高优先级元素进行常数时间访问,从而使堆成为实现优先队列的高效数据结构。 保证访问极端值:在最大堆中,最大元素始终位于根部,而在最小堆中,最小元素始终位于根部。此属性确保堆提供对最大或最小元素的保证访问,这在需要快速访问极端值的算法中很有用。 空间效率:堆结构是空间高效的,因为它将元素组织在一个完全二叉树中,与链表或动态数组等其他数据结构相比,它通常占用更少的内存。 堆排序算法:堆数据结构是堆排序算法的基础,堆排序是一种有效的方法,其最坏情况时间复杂度为 O(n log n)。这使得堆排序成为对大型数据集进行排序的稳健选择。 堆的缺点灵活性差:堆结构旨在维护元素的特定顺序,这限制了其灵活性。这使其不太适合需要更灵活数据结构的应用程序。 搜索效率低下:虽然堆提供了对顶部元素的有效访问,但它们并不适合搜索特定元素。在堆中查找元素需要遍历整个树,导致时间复杂度为 O(n)。 不稳定性:堆不是稳定的数据结构,这意味着具有相等值的元素的相对顺序在插入或修改过程中可能不会保留。 内存管理挑战:堆需要动态内存分配,这在内存资源有限的系统中可能会出现问题。此外,管理堆的分配内存可能很复杂,并且容易出错。 复杂性考虑:虽然堆允许高效的插入、删除和优先队列操作,但最坏情况时间复杂度为 O(n log n)。对于需要更快的算法的应用程序来说,这可能不是最佳选择。 |
当给定一个整数数组 nums[] 和一个正整数 K 时,任务是找到从数组中选择的最多值,使得其二进制表示中的 1 的总数最多为 K。示例 1:输入:int……
阅读 3 分钟
埃拉托斯特尼筛法是一种古老而有效的算法,用于查找小于给定限制的所有素数。该算法以古希腊数学家埃拉托斯特尼命名,经受住了时间的考验,仍然是数论和...中的基本概念。
阅读 4 分钟
Java 中的不可变性是指创建其状态在创建后无法更改的对象。不可变性在并发编程中特别有用,因为它消除了同步的需要并提供了一些线程保护。实现一致性改进的一种方法是创建……
阅读 13 分钟
二叉树的锯齿形遍历意味着顶层的节点从左到右遍历,然后下一层从右到左遍历,如此循环,不断改变方向,从左到右,然后...
阅读 10 分钟
在 Java 中,最常见的搜索程序是搜索员工详细信息。员工是一个实体,可以有几个属性,如 id、name 和 department 等。为了创建一个 Java 员工详细信息程序,我们需要为员工实体创建一个类,并...
阅读 2 分钟
在给定的输入数组中,任务是找到最长可整除子集的大小。如果子集中的每对(p,q)满足 p 整除 q(p % q = 0)或 q 整除 p,则该子集被称为可整除的...
阅读 6 分钟
什么是 TDD?测试驱动开发(TDD)是一种软件开发过程。顾名思义,它涉及利用测试来指导应用程序开发,从而从一开始就实现简单、迭代的实现,并具有良好的测试覆盖率。测试驱动的设计和构建每个功能的测试...
阅读 3 分钟
在软件开发领域,编程语言不断发展以满足行业需求。随着新功能的引入和现有功能的改进,某些语言元素可能会过时或被认为不太理想。为解决此问题,Java 编程...
阅读 3 分钟
在软件开发的世界里,高效地管理任务和编排工作流程对于任何应用程序的成功都至关重要。开发人员面临的一个常见挑战是在特定时间间隔安排和执行作业。在本节中,我们将探讨一个作业的设计和实现...
阅读 6 分钟
?图像压缩允许我们在不显著影响视觉质量的情况下减小图像文件的大小。有两种压缩类型。首先,我们使用有损压缩来接受降低的图像质量,同时实现更小的文件大小。例如,我们有...
5 分钟阅读
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India