一、堆的核心概念与结构特性
堆的本质是满足特定规则的完全二叉树,同时通过数组存储以最大化空间利用率(用连续数组存储完全二叉树,无需额外存储指针,几乎没有内存浪费)。
1. 堆的定义
- 看着像一棵'层层填满、最后一层靠左排'的树(完全二叉树),但实际是存在连续数组里的;
- 有个铁规矩:要么每个节点都比自己的子节点大/相等(这叫大根堆,最顶上的是最大的数),要么每个节点都比自己的子节点小/相等(这叫小根堆,最顶上的是最小的数);
- 核心用处就是快速找最大/最小数,不用挨个遍历,直接拿最顶上的就行。
2. 核心特性
逻辑结构:必为完全二叉树,不存在'断层'节点,所有叶子节点集中在最后两层,且最后一层节点靠左排列;
存储结构:物理上是连续数组,通过索引映射父子关系(设节点索引为 i):
父节点索引:(i - 1) / 2(向下取整);左子节点索引:2 * i + 1;右子节点索引:2 * i + 2;
最值特性:堆顶(数组第一个元素)始终是集合中的最大值(大根堆)或最小值(小根堆)。
3. 直观示例

小根堆:逻辑上根节点最小,数组存储为 [10, 15, 25, 56, 30, 70];
大根堆:逻辑上根节点最大,数组存储为 [70, 56, 30, 15, 25, 10]。
二、堆的实现
1. 堆的结构
堆的底层是用数组实现的,因此它的结构和顺序表的结构基本一致,具体定义如下:
typedef int HpDataType;
typedef struct Heap {
HpDataType* a;
int size;
int capacity;
} heap;
2. 堆的初始化
// 初始化堆
void HeapInit(heap* php) {
assert(php);
php->a = (HpDataType*)malloc(sizeof(HpDataType) * 4);
if (php->a == NULL) {
perror("malloc");
return;
}
php->capacity = 4;
php->size = 0;
}


















