数据结构:堆(Heap)
堆是计算机科学中核心的数据结构之一,基于完全二叉树构建,兼具高效的插入、删除和极值查询能力,广泛应用于优先队列、堆排序、TopK 问题等场景。
一、堆的定义与核心性质
1.1 本质定义
堆是一种完全二叉树(Complete Binary Tree),同时满足堆序性(Heap Property)。完全二叉树的定义是:除最后一层外,每一层的节点数均为最大值,且最后一层的节点从左到右连续排列(无空洞)。这种结构决定了堆可以用数组高效存储,无需额外指针开销。
1.2 堆序性规则
堆序性是堆与普通完全二叉树的核心区别,分为两种类型:
- 大根堆(Max Heap):每个父节点的值 大于等于 其左右子节点的值(
parent.val ≥ left.val && parent.val ≥ right.val),堆顶(根节点)是整个堆的最大值。 - 小根堆(Min Heap):每个父节点的值 小于等于 其左右子节点的值(
parent.val ≤ left.val && parent.val ≤ right.val),堆顶是整个堆的最小值。
1.3 与二叉搜索树(BST)的区别
堆和 BST 常被混淆,但核心目标完全不同:
| 特性 | 堆(大根堆/小根堆) | 二叉搜索树(BST) |
|---|---|---|
| 结构要求 | 完全二叉树 | 任意二叉树(通常平衡化) |
| 有序性 | 仅父子节点满足堆序(全局无序) | 左子树 < 根 < 右子树(全局有序) |
| 核心操作效率 | 插入/删除堆顶 O(logn),查极值 O(1) | 插入/删除/查找 O(logn)(平衡 BST) |
| 适用场景 | 优先队列、TopK、堆排序 | 动态查找、有序遍历 |
二、堆的存储结构
由于堆是完全二叉树,无空洞节点,因此数组是堆的最优存储方式,无需额外空间存储指针。数组与二叉树节点的映射关系如下:
假设堆的数组为 vector<T> heap,对于索引为 i 的节点(从 0 开始计数):
- 父节点索引:
parent = (i - 1) / 2(整数除法,自动向下取整) - 左子节点索引:
left = 2 * i + 1 - 右子节点索引:
right = 2 * i + 2
示例:小根堆 [2, 5, 3, 8, 7, 6] 对应的完全二叉树结构:
2 (i=0)
/ \
5(i=1) 3(i=2)
/ \ /
8(i=) (=) (=)


