堆是一颗完全二叉树,支持高效插入一个数,查找最大(小)值。

小根堆:对于任意节点u,满足u是{u,u2(左儿子),u2+1(右儿子)}中的最小元素,如何维护呢?
利用push, up操作

void down(int x)
{
    int t = x;
    if (x * 2 <= sz && h[x * 2] < h[t])t = x * 2;
    if (x * 2 +1 <= sz && h[x * 2 + 1] < h[t])t = x * 2 + 1;
    if (t != x)
    {
        swap(h[t], h[x]);
        down(t);
    }
}
void up(int x)
{
    while (x / 2 && h[x / 2] > h[x])
    {
        swap(h[x], h[x / 2]);
        x /= 2;
    }
}

堆的基本操作 (小根堆)

  1. 插入一个数 heap[size++] = x; up(size);
  2. 求最小值 heap[1]
  3. 删除最小元素 heap[1] = heap[size]; size--; down(1)
  4. 删除任意元素 heap[k] = heap[size]; size--; down(k); / up(k);
  5. 修改任意元素 heap[k] = x; down(k); / up(k);

O(n)建堆: for (int i = n / 2; i >= 1; i--)down(i);

posted @ 2025-03-17 18:10  闫柏军  阅读(40)  评论(0)    收藏  举报