目录
1. 堆的本质:特殊的完全二叉树
堆是一种基于完全二叉树实现的数据结构,必须满足以下两个核心特性:
-
结构性:必须是完全二叉树(所有层除最后一层外完全填满,最后一层节点左对齐)
-
有序性:满足堆属性(父节点与子节点有明确的大小关系)
完全二叉树的特性
特性 | 说明 | 示例(数组索引从0开始) |
---|---|---|
节点填充顺序 | 按层从左到右填充 | 层序遍历顺序存储 |
数组存储优势 | 可用数组高效表示,无需指针 | 父节点索引:(i-1)/2 |
高度计算 | 最小高度为⌊log₂n⌋ | 子节点索引:2i+1 (左)、2i+2 (右) |
2. 堆的类型与二叉树形态
堆通过有序性分为两类,体现为二叉树的不同节点关系:
堆类型 | 有序性规则(父节点 vs 子节点) | 二叉树形态示例(最大堆) |
---|---|---|
最大堆 | 父节点值 ≥ 子节点值 | 10 / \ 8 9 / \ / 5 6 7 |
最小堆 | 父节点值 ≤ 子节点值 | 1 / \ 2 3 / \ / 4 5 6 |
3. 堆与普通二叉树的区别
特性 | 普通二叉树 | 堆(完全二叉树 + 堆属性) |
---|---|---|
结构要求 | 任意形态 | 必须为完全二叉树 |
节点关系 | 无强制大小要求 | 父节点与子节点有严格大小关系 |
存储方式 | 通常用链表存储 | 通常用数组存储 |
典型应用 | 一般数据存储 | 高效排序、优先队列 |
4. 堆与二叉搜索树(BST)的对比
特性 | 二叉搜索树(BST) | 堆 |
---|---|---|
节点顺序 | 左 < 父 < 右 | 父与子有大小关系(无左右顺序) |
查找效率 | 平均O(log n) | 不支持快速查找(需遍历) |
插入/删除效率 | 平均O(log n) | 插入O(log n),删除根O(log n) |
主要用途 | 动态数据检索 | 快速获取极值、排序 |
5. 堆的数组表示原理
由于堆是完全二叉树,可用数组紧凑存储,通过索引计算访问节点:
-
父节点索引:
parent(i) = (i-1)/2
(向下取整) -
左子节点索引:
left(i) = 2*i + 1
-
右子节点索引:
right(i) = 2*i + 2
示例(数组[10, 8, 9, 5, 6, 7]
对应的堆结构):
索引 0: 10 (根)
├─左子索引1: 8
│ ├─左子索引3: 5
│ └─右子索引4: 6
└─右子索引2: 9
└─左子索引5: 7
6. 堆的典型操作与二叉树遍历
操作 | 时间复杂度 | 二叉树操作关联 |
---|---|---|
插入元素 | O(log n) | 从最后节点上浮(类似后序遍历调整) |
删除根节点 | O(log n) | 末尾元素替换根后下沉(类似层次调整) |
构建堆 | O(n) | 自底向上逐层调整(反向层次遍历) |
获取极值 | O(1) | 直接访问根节点 |
7. 堆的应用场景
-
堆排序:时间复杂度稳定为O(n log n)的排序算法
-
优先队列:操作系统进程调度、Dijkstra算法
-
Top K问题:快速获取最大/最小的K个元素
-
合并有序序列:多路归并时高效管理当前最小值
总结
堆本质上是通过完全二叉树的结构约束和节点值的顺序约束实现的特殊数据结构。其数组存储方式和高效调整算法(heapify
)的结合,使得堆在需要快速获取极值的场景中表现出色。理解堆与二叉树的关系,有助于掌握优先队列、堆排序等核心算法,并为学习更复杂的树结构(如AVL树、B树)奠定基础。