贡献者: 待更新
(本文根据 CC-BY-SA 协议转载自原搜狗科学百科对英文维基百科的翻译)
在计算机科学中,堆是一种特殊的基于树的数据结构,本质上是一棵几乎完全的[1]树,它满足堆属性:在最大堆中,对于任意给定的节点 C,如果 P 是 C 的父节点,那么 P 的键(值)大于或等于 C 的键。在最小堆中,P 的键小于或等于 C 的键。堆 “顶部” 的节点(没有父节点)称为根节点。
堆是称为优先队列的抽象数据类型的最有效实现,事实上优先队列通常被称为 “堆”,不管它们是如何实现的。在堆中,最高(或最低)优先级的元素总是存储在根节点。然而,堆不是排序结构,它可以被认为是部分有序的。当需要重复移除优先级最高(或最低)的对象时,堆是一种有用的数据结构。
堆的一个常见实现是二叉堆,其中树是二叉树(见图)。堆数据结构,特别是二叉堆,是由 J. W. J. Williams 在 1964 年引入的,作为堆排序算法的数据结构。[2] 堆在一些高效的图算法中也很重要,比如 Dijkstra 算法。当堆是一棵完全二叉树时,它有一个最小的可能高度——一个有 N 个节点的堆,对于每个节点,一个分支总是有 loga N 的高度。
注意,如图所示,兄弟和堂兄弟之间没有隐含的排序,也没有有序遍历的隐含序列(例如,在二叉搜索树中)。上面提到的堆关系仅适用于节点和它们的父亲、祖父等之间。每个节点可以拥有的最大子节点数取决于堆的类型。
涉及堆的常见操作有:
基础
创建
检查
内部的
堆通常在数组(固定大小或动态数组)中实现,并且不需要元素之间的指针。元素插入堆或从堆中删除后,可能会违反堆性质,必须通过内部操作来平衡堆。
二叉堆可以用单独使用数组的非常节省空间的方式来表示。第一个(或最后一个)元素将包含根元素。数组接下来两个元素包含根元素的孩子。接下来的四个包含两个子节点的四个子节点,等等。因此,在位置 n 的节点的子节点将在以 1 为起点编号数组的 2n 和 2n+1 位置,或者 “以 0 为起点编号数组的 2n+1 和 2n+2 位置。这允许通过简单的索引计算来向上或向下移动树。允许通过向上筛选或向下筛选操作(交换无序元素)来完成平衡堆。因为我们可以从一个数组构建一个堆,而不需要额外的内存(例如,对于节点),所以 heapsort 可以用来就地排序一个数组。
不同类型的堆以不同的方式实现操作,但值得注意的是,插入通常是通过在堆的末尾第一个可用空间中添加新元素来完成的。这通常会违反堆性质,因此元素会被向上筛选,直到堆性质被重新建立。类似地,删除根元素是通过移动根元素,然后将最后一个元素放入根并向下筛选以重新平衡。因此,替换是通过删除根并将新元素放入根并向下筛选来完成的,和先 pop(向下筛选最后一个元素),再 push(向上筛选新元素)后相比,避免了向上筛选步骤。
从给定的元素数组中构造二叉(或 d 叉)堆可以使用经典弗洛伊德算法在线性时间内执行,最差情况下的比较次数等于 2N − 2s2(N) − e2(N) (对于二叉堆),其中 s2(N)是 N 的二进制表示的所有数字的总和,e2(N)是 N 的素数因子分解中的 2 的指数,[6] 这比连续插入原始空堆的序列更快,该操作是对数线性的。
以下是各种堆数据结构的时间复杂度。函数名假设一个最小堆。
In the following time complexities[7] O(f) is an asymptotic upper bound and Θ(f) is an asymptotically tight bound (see Big O notation). Function names assume a min-heap.
堆数据结构有许多应用。
[1] ^CORMEN, THOMAS H. (2009). INTRODUCTION TO ALGORITHMS. United States of America: The MIT Press Cambridge, Massachusetts London, England. pp. 151–152. ISBN 978-0-262-03384-8..
[2] ^Williams, J. W. J. (1964), "Algorithm 232 - Heapsort", Communications of the ACM, 7 (6): 347–348, doi:10.1145/512274.512284.
[3] ^The Python Standard Library, 8.4. heapq — Heap queue algorithm, heapq.heappush.
[4] ^The Python Standard Library, 8.4. heapq — Heap queue algorithm, heapq.heappop.
[5] ^The Python Standard Library, 8.4. heapq — Heap queue algorithm, heapq.heapreplace.
[6] ^Suchenek, Marek A. (2012), "Elementary Yet Precise Worst-Case Analysis of Floyd's Heap-Construction Program", Fundamenta Informaticae, IOS Press, 120 (1): 75–92, doi:10.3233/FI-2012-751..
[7] ^Cormen, Thomas H.(英语:Thomas H. Cormen); Leiserson, Charles E. ; Rivest, Ronald L. (1990). Introduction to Algorithms (1st ed.). MIT Press and McGraw-Hill. ISBN 0-262-03141-8.CS1 maint: Multiple names: authors list (link).
[8] ^Fredman, Michael Lawrence; Tarjan, Robert E. (July 1987). "Fibonacci heaps and their uses in improved network optimization algorithms" (PDF). Journal of the Association for Computing Machinery. 34 (3): 596–615. doi:10.1145/28869.28874..
[9] ^Iacono, John (2000), "Improved upper bounds for pairing heaps", Proc. 7th Scandinavian Workshop on Algorithm Theory (PDF), Lecture Notes in Computer Science, 1851, Springer-Verlag, pp. 63–77, arXiv:1110.4428, doi:10.1007/3-540-44985-X_5, ISBN 3-540-67690-2.
[10] ^Brodal, Gerth S. (1996), "Worst-Case Efficient Priority Queues" (PDF), Proc. 7th Annual ACM-SIAM Symposium on Discrete Algorithms, pp. 52–58.
[11] ^Haeupler, Bernhard; Sen, Siddhartha; Tarjan, Robert E. (November 2011). "Rank-pairing heaps" (PDF). SIAM J. Computing: 1463–1485. doi:10.1137/100785351..
[12] ^Brodal, G. S. L.; Lagogiannis, G.; Tarjan, R. E. (2012). Strict Fibonacci heaps (PDF). Proceedings of the 44th symposium on Theory of Computing - STOC '12. p. 1177. doi:10.1145/2213977.2214082. ISBN 9781450312455..
[13] ^Goodrich, Michael T.; Tamassia, Roberto (2004). "7.3.6. Bottom-Up Heap Construction". Data Structures and Algorithms in Java (3rd ed.). pp. 338–341. ISBN 0-471-46983-1..
[14] ^Fredman, Michael Lawrence (July 1999). "On the Efficiency of Pairing Heaps and Related Data Structures" (PDF). Journal of the Association for Computing Machinery. 46 (4): 473–501. doi:10.1145/320211.320214..
[15] ^Pettie, Seth (2005). Towards a Final Analysis of Pairing Heaps (PDF). FOCS '05 Proceedings of the 46th Annual IEEE Symposium on Foundations of Computer Science. pp. 174–183. CiteSeerX 10.1.1.549.471. doi:10.1109/SFCS.2005.75. ISBN 0-7695-2468-0..
[16] ^Frederickson, Greg N. (1993), "An Optimal Algorithm for Selection in a Min-Heap", Information and Computation (PDF), 104 (2), Academic Press, pp. 197–214, doi:10.1006/inco.1993.1030.