斐波那契堆的实现相对复杂,涉及到许多细节。以下是一个简单的C++实现,包含了插入、合并、删除最小元素和减小关键字等基本操作:
#include <iostream>
#include <vector>
#include <cmath>
#include <limits>
// 定义斐波那契堆节点
class FibonacciHeapNode {
public:
int key; // 节点值
int degree; // 节点度数
bool marked; // 是否被标记
FibonacciHeapNode* parent; // 父节点
FibonacciHeapNode* child; // 第一个子节点
FibonacciHeapNode* left; // 左兄弟节点
FibonacciHeapNode* right; // 右兄弟节点
// 构造函数
FibonacciHeapNode(int k) : key(k), degree(0), marked(false), parent(nullptr), child(nullptr), left(this), right(this) {}
};
// 定义斐波那契堆
class FibonacciHeap {
private:
FibonacciHeapNode* minNode; // 最小节点
int numNodes; // 节点数目
public:
// 构造函数
FibonacciHeap() : minNode(nullptr), numNodes(0) {}
// 插入操作
void insert(int key) {
FibonacciHeapNode* newNode = new FibonacciHeapNode(key);
if (!minNode) {
minNode = newNode;
} else {
newNode->left = minNode->left;
newNode->right = minNode;
minNode->left->right = newNode;
minNode->left = newNode;
if (key < minNode->key) minNode = newNode;
}
numNodes++;
}
// 合并操作
void merge(FibonacciHeap* other) {
if (!other || !other->minNode) return;
if (!minNode) {
minNode = other->minNode;
} else {
FibonacciHeapNode* thisRight = minNode->right;
FibonacciHeapNode* otherLeft = other->minNode->left;
minNode->right = other->minNode;
other->minNode->left = minNode;
thisRight->left = otherLeft;
otherLeft->right = thisRight;
if (other->minNode->key < minNode->key) minNode = other->minNode;
}
numNodes += other->numNodes;
other->minNode = nullptr;
other->numNodes = 0;
}
// 删除最小元素操作
int removeMin() {
if (!minNode) return std::numeric_limits<int>::max();
FibonacciHeapNode* min = minNode;
if (minNode->child) {
FibonacciHeapNode* child = minNode->child;
do {
FibonacciHeapNode* nextChild = child->right;
minNode->left->right = child;
child->right = minNode;
minNode->left = child;
child->parent = nullptr;
child = nextChild;
} while (child != minNode->child);
}
minNode->left->right = minNode->right;
minNode->right->left = minNode->left;
if (minNode == minNode->right) {
minNode = nullptr;
} else {
minNode = minNode->right;
consolidate();
}
numNodes--;
int minKey = min->key;
delete min;
return minKey;
}
// 减小关键字操作
void decreaseKey(FibonacciHeapNode* node, int newKey) {
if (!node || newKey >= node->key) return;
node->key = newKey;
FibonacciHeapNode* parent = node->parent;
if (parent && node->key < parent->key) {
cut(node, parent);
cascadingCut(parent);
}
if (node->key < minNode->key) minNode = node;
}
// 删除节点操作
void deleteNode(FibonacciHeapNode* node) {
decreaseKey(node, std::numeric_limits<int>::min());
removeMin();
}
private:
// 合并具有相同度数的树
void consolidate() {
int maxDegree = std::ceil(std::log2(numNodes)) + 1;
std::vector<FibonacciHeapNode*> degreeTable(maxDegree, nullptr);
FibonacciHeapNode* curr = minNode;
do {
FibonacciHeapNode* next = curr->right;
int degree = curr->degree;
while (degreeTable[degree]) {
FibonacciHeapNode* other = degreeTable[degree];
if (curr->key > other->key) std::swap(curr, other);
link(other, curr);
degreeTable[degree] = nullptr;
degree++;
}
degreeTable[degree] = curr;
curr = next;
} while (curr != minNode);
minNode = nullptr;
for (int i = 0; i < maxDegree; ++i) {
if (degreeTable[i]) {
if (!minNode) {
minNode = degreeTable[i];
} else {
degreeTable[i]->left->right = degreeTable[i]->right;
degreeTable[i]->right->left = degreeTable[i]->left;
degreeTable[i]->left = minNode->left;
degreeTable[i]->right = minNode;
minNode->left->right = degreeTable[i];
minNode->left = degreeTable[i];
if (degreeTable[i]->key < minNode->key) minNode = degreeTable[i];
}
}
}
}
// 将other合并到root中
void link(FibonacciHeapNode* other, FibonacciHeapNode* root) {
other->left->right = other->right;
other->right->left = other->left;
other->parent = root;
if (!root->child) {
root->child = other;
other->left = other->right = other;
} else {
other->left = root->child->left;
other->right = root->child;
root->child->left->right = other;
root->child->left = other;
}
root->degree++;
other->marked = false;
}
// 剪切节点node和其父节点的链接,并将node添加到根列表中
void cut(FibonacciHeapNode* node, FibonacciHeapNode* parent) {
if (!parent->child) return;
if (node->right == node) {
parent->child = nullptr;
} else {
node->left->right = node->right;
node->right->left = node->left;
if (parent->child == node) parent->child = node->right;
}
parent->degree--;
node->left = minNode->left;
node->right = minNode;
minNode->left->right = node;
minNode->left = node;
node->parent = nullptr;
node->marked = false;
}
// 级联剪切,直到遇到未被标记的节点或根节点
void cascadingCut(FibonacciHeapNode* node) {
FibonacciHeapNode* parent = node->parent;
if (parent) {
if (!node->marked) {
node->marked = true;
} else {
cut(node, parent);
cascadingCut(parent);
}
}
}
};
int main() {
FibonacciHeap heap;
heap.insert(5);
heap.insert(10);
heap.insert(3);
std::cout << "Min element: " << heap.removeMin() << std::endl;
return 0;
}