📜  配对堆(1)

📅  最后修改于: 2023-12-03 14:58:09.889000             🧑  作者: Mango

配对堆(Pairing Heap)

配对堆是一种基于树结构的、可合并的优先队列数据结构,它的特点是在插入、删除、取出最大元素的操作中都非常快速。

基本操作
  • MakeHeap(): 新建一个空的配对堆,这个过程的时间复杂度为 $O(1)$;
  • Insert(x): 将元素 $x$ 插入到配对堆中,这个过程的时间复杂度为 $O(1)$;
  • Merge(h1, h2): 将两个配对堆合并成一个大的配对堆,这个过程的时间复杂度为 $O(\log n)$;
  • FindMax(): 查找并返回最大元素,这个过程的时间复杂度为 $O(1)$;
  • DeleteMax(): 删除最大元素,这个过程的时间复杂度为 $O(\log n)$。
实现原理

配对堆是一棵多叉树,并且符合堆的性质,即堆顶元素是最大的。它的实现基于以下原理:

  • 删除最大元素时,将其所有的子节点插入到一个新的配对堆中,并递归进行配对合并,形成一棵新的多叉树;
  • 插入元素时,直接将其作为一个单独的树插入到堆中即可;
  • 合并两棵树时,将其中适合做堆顶的树的根节点作为合并后树的根节点,并将剩余的子树递归进行配对合并,形成一棵新的多叉树。
代码实现

下面是C++实现的代码片段:

struct Node {
    int val;
    Node *left, *right;
    Node(int v): val(v), left(nullptr), right(nullptr) {}
};

Node* Merge(Node *h1, Node *h2) {
    if (!h1) return h2;
    if (!h2) return h1;
    if (h1->val < h2->val) swap(h1, h2);
    h2->right = h1->left;
    if (h2->right) h2->right->left = h2;
    h1->left = h2;
    h2->parent = h1;
    return h1;
}

void Insert(Node *& root, int val) {
    root = Merge(root, new Node(val));
}

void DeleteMax(Node *& root) {
    Node *toDel = root;
    root = Merge(root->left, root->right);
    delete toDel;
}

int FindMax(Node * root) {
    return root->val;
}
总结

配对堆是一种实现简单、插入、合并、查找最大元素和删除最大元素等操作均可在 $O(\log n)$ 时间内完成的优先队列数据结构。它的代码实现也非常简洁易懂,适合各种编程竞赛和算法竞赛题目中的解决方案。