利用完全二叉大根堆,实现原地(In-place)、严格 $O(N \log N)$ 物理排序
堆排序是利用完全二叉堆(Binary Heap)进行的选择排序。它包含两个核心阶段:
siftDown 向下调整,使其均大于或等于孩子节点。siftDown 向下调整。// 堆排序核心代码
void siftDown(int a[], int i, int n) {
int parent = i;
int child = 2 * parent + 1; // 左孩子索引
while (child < n) {
// 若有右孩子且右孩子更大,则指向右孩子
if (child + 1 < n && a[child] < a[child + 1]) child++;
// 父节点已大于等于最大子节点,则调整完毕
if (a[parent] >= a[child]) break;
swap(a[parent], a[child]); // 违背堆序,执行对调
parent = child;
child = 2 * parent + 1;
}
}
void heapSort(int a[], int n) {
// 1. 自底向上建堆
for (int i = n / 2 - 1; i >= 0; i--) siftDown(a, i, n);
// 2. 堆顶置换并调整
for (int i = n - 1; i > 0; i--) {
swap(a[0], a[i]); // 堆顶最大值与堆尾交换
siftDown(a, 0, i); // 重新向下调整维护堆
}
}