基于完全二叉树的高效优先队列实现,支持 $O(\log N)$ 级的最值维护
二叉堆是一种特殊的完全二叉树,存储在一维数组中。它满足如下性质:
设节点在一维数组中的索引为 $i$,则:
class MaxHeap {
private:
vector<int> heap;
// 向上调整:用于插入元素后维护堆
void siftUp(int i) {
while (i > 0) {
int p = (i - 1) / 2;
if (heap[i] <= heap[p]) break;
swap(heap[i], heap[p]); // 与父节点交换
i = p;
}
}
// 向下调整:用于提取堆顶后维护堆
void siftDown(int i) {
int n = heap.size();
while (2 * i + 1 < n) {
int left = 2 * i + 1;
int right = 2 * i + 2;
int largest = left;
// 找出左、右孩子中较大者
if (right < n && heap[right] > heap[left]) {
largest = right;
}
if (heap[i] >= heap[largest]) break;
swap(heap[i], heap[largest]); // 与较大孩子交换
i = largest;
}
}
public:
void insert(int val) {
heap.push_back(val); // 放到末尾
siftUp(heap.size() - 1); // 向上调整
}
int extractMax() {
if (heap.empty()) return -1;
int maxVal = heap[0];
heap[0] = heap.back(); // 尾部移到头部
heap.pop_back();
siftDown(0); // 向下调整
return maxVal;
}
};