堆与优先级队列 (Heaps & Priority Queues)
为什么堆很重要
堆提供了对最小或最大元素的高效访问——这对于 基于优先级的处理至关重要:
- 任务调度:操作系统进程调度、异步作业队列。
- 图算法:Dijkstra 最短路径、Prim 最小生成树。
- 流处理:在持续的数据流中寻找前 K 个最大/最小元素。
- 事件模拟:按时间顺序精准处理离散事件。
实际影响:Java 的 PriorityQueue 利用二叉堆实现了 的插入和 的最值访问。从 100 万个元素中找出前 10 名,使用堆仅需约 20 次操作,而全量排序则需 1000 万次比较。
核心概念
二叉堆结构
堆是一棵完全二叉树,且满足堆属性:
- 最大堆 (Max-Heap):父节点的值 子节点。
- 最小堆 (Min-Heap):父节点的值 子节点。
数组实现原理
二叉堆通常用数组存储,逻辑结构与物理索引的映射公式如下:
对于索引为 i 的节点:
- 父节点:
(i - 1) / 2 - 左子节点