DSA 笔记 -> Heap

Heap and Heapsort

(部分内容使用ChatGPT 5.1生成)

Heap(堆)是什么?

Heap 是一种特殊的“几乎完全满”的二叉树(almost perfect binary tree)。
它不仅结构特别,而且还满足一个很重要的性质:堆序性(heap order property)。

Heap 的两个核心特性

  1. 结构性质:完全二叉树
    也被叫做 binary heap,要求:
  • 除了最底层,其他每一层都是满的
  • 最底层如果不满,必须从左往右依次填满
  • 没有缺口(holes)

这使得 堆非常适合用数组实现,因为它的形状很规则。

举例:
对数组中下标为 i 的节点:

  • 左孩子在 2*i + 1
  • 右孩子在 2*i + 2
  • 父节点在 (i−1)/2

holes 的意思:

对于完全二叉树,每一层的节点数是2的层数-1(n-1)次方。

  • 第一层 2^(1-1) = 1
  • 第二层 2^(2-1) = 2
  • 第三层 2^(3-1) = 4
  1. 堆序性:父节点必须小于或等于子节点(最小堆)
    子节点的数值必须大于父节点的数值,这样的最小值永远在根节点(顶端)。

insert()

1
2
3
4
5
6
7
8
9
10
11
12
insert(x)
1. IF ISFULL(A)
2. return False // 检查是不是满了,插不进去了
3. // percolate up
4. hole = size++ // 在末尾挖一个洞,先赋值再自增
5. WHILE hole > 0 AND x < A[(hole-1)/2]
// hole = 0,到根了不能上升
// x < A[(hole-1)/2]子节点小于父节点,交换父节点和hole
6. A[hole] = A[(hole-1)/2]
hole = (hole-1)/2
7. A[hole] = x
8. return True

解释关键变量:

  • hole:当前“洞”的位置(用来“挖坑”往上走)

  • size++:插入前堆有 size 个元素,新元素先占用 A[size] 位置,size 再加 1

不用担心,因为既然hole能到这个位置,那么之前的数据都窜下去了,给父节点赋到子节点不会丢失内容。

deleteMin()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
deleteMin()
1. IF ISEMPTY(A)
2. return -1 // 空了不能删
3. min = A[0], hole = 0, x = A[--size]
// 删掉的最小值要返回,然后给hole设成这个位置,移动hole
// size-1是最后一个元素的下标,x = 最后一个元素的值
4. // percolate down
5. WHILE A[hole] has children
// 用2*hole+1和size比较
// 注意如果2*hole+2没有东西了的情况,sid直接为2*hole+1
6. sid = index of A[hole]’s smaller child
7. IF x <= A[sid]
8. BREAK
// 如果hole往下降到正确的位置,停止下降
9. A[hole] = A[sid]
10. hole = sid
11. A[hole] = x
12. return min

关键变量解释:
sid: 实际上循环是 while ((2*hole+1) < size)

1
2
3
4
5
if ((2*hole+2) >= size) {
bid = 2*hole+1; // Only left child exists
} else {
bid = (A[2*hole+1] < A[2*hole+2] ? (2*hole+1) : (2*hole+2)); // Select smaller child
}

heapSort()

我们不需要多余的空间来进行排序,一个数组中:

直接给他们归成MaxHeap的形式,来存档。

MaxHeap就是给MinHeap反过来。insert的过程,将第5步的<换为>即可。deleteMin换为deleteMax,然后更换sidbid,就是给bid赋值过程的判断反向,BREAK也换为>=

存进去,倒着deleteMax出来,……

1
2
3
4
5
6
7
8
9
public static void heapSort(int A[]) {
MaxHeap heap = new MaxHeap(A); // Heap backed by same array
for (int x : A) {
heap.insert(x); // Build heap one value at a time
}
for (int i = (heap.size - 1); i > 0; i--) {
A[i] = heap.deleteMax(); // Pull max into sorted suffix
}
}

DSA 笔记 -> Heap
https://blog.zlicdt.top/2025/11/14/algorithm-heap/
作者
zlicdt
发布于
2025年11月14日
许可协议