【知识点】配对堆

定义

配对堆是一棵满足堆性质的带权多叉树。它是一种可并堆,可以快速和其他配对堆合并。速度快,结构简单,不可持久化。

存储方式

一般采用儿子-兄弟表示法,每个结点保存其第一个儿子与第一个兄弟所在指针,若不存在则存为nullptr。

操作

查询最小值

直接访问根节点的值即可,时间复杂度为O(1)。

合并

两个配对堆,根更大的那个,成为根更小的那个的第一个儿子。

Node* meld(Node* x, Node* y) {
  if (x == nullptr) return y;
  if (y == nullptr) return x;
  if (x->v > y->v) std::swap(x, y);
  y->sibling = x->child;
  x->child = y;
  return x;
}

合并的时间复杂度为O(1)。

删除最小值

首先,访问根节点,并删除。然后,原根节点的所有儿子将形成n个新的配对堆。从左到右,使新的配对堆两两配对合并,形成几个新的配对堆。这些新的配对堆,从右到左,前两个合并出的新配对堆与第三个合并,以此类推……
image

Node* merges(Node* x) {
  if (x == nullptr || x->sibling == nullptr)
    return x;
  Node* y = x->sibling;
  Node* c = y->sibling;
  x->sibling = y->sibling = nullptr;
  return meld(merges(c), meld(x, y));
}

Node* delete_min(Node* x) {
  Node* t = merges(x->child);
  delete x;
  return t;
}

删除的均摊复杂度为O(logn),注意严格按照上述顺序进行合并。

posted @ 2025-07-31 20:29  Alkaid16  阅读(28)  评论(0)    收藏  举报