Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
FibonacciHeap.h
Go to the documentation of this file.
1
32#pragma once
33
35
36#include <array>
37#include <functional>
38#include <utility>
39
40namespace ogdf {
41
42
44template<typename T>
46 template<typename, typename>
47 friend class FibonacciHeap;
48
49protected:
51
52 size_t rank;
53 bool marked;
54
59
63
65 explicit FibonacciHeapNode(const T& nodeValue)
67 , rank(0)
68 , marked(false)
70 , child(nullptr)
71 , prev(this)
72 , next(this) { }
73};
74
76
86template<typename T, typename C = std::less<T>>
87class FibonacciHeap : public HeapBase<FibonacciHeap<T, C>, FibonacciHeapNode<T>, T, C> {
89
90public:
97 explicit FibonacciHeap(const C& cmp = C(), int initialSize = -1);
98
105 virtual ~FibonacciHeap();
106
108 const T& top() const override;
109
116 FibonacciHeapNode<T>* push(const T& value) override;
117
123 void pop() override;
124
134 void decrease(FibonacciHeapNode<T>* heapNode, const T& value) override;
135
143 void merge(FibonacciHeap<T, C>& other) override;
144
151 const T& value(FibonacciHeapNode<T>* heapNode) const override { return heapNode->value; }
152
153private:
158
160 std::array<FibonacciHeapNode<T>*, sizeof(size_t) * 8> m_ranked;
161
163 void remove();
165 void compress();
166
177
180};
181
182template<typename T, typename C>
183FibonacciHeap<T, C>::FibonacciHeap(const C& cmp, int /* unused parameter */)
184 : base_type(cmp), m_minimal(nullptr), m_knot(new FibonacciHeapNode<T>()) {
185 m_ranked.fill(nullptr);
186}
187
188template<typename T, typename C>
190 release(m_knot);
191}
192
193template<typename T, typename C>
195 if (heapNode == nullptr) {
196 return;
197 }
198
200 do {
201 release(heapNode->child);
202
203 FibonacciHeapNode<T>* next = heapNode->next;
204 delete heapNode;
205 heapNode = next;
206 } while (heapNode != end);
207}
208
209template<typename T, typename C>
210inline const T& FibonacciHeap<T, C>::top() const {
211 OGDF_ASSERT(m_minimal != nullptr);
212 return m_minimal->value;
213}
214
215template<typename T, typename C>
218 splice(m_knot, heapNode);
219
220 if (m_minimal == nullptr || this->comparator()(heapNode->value, m_minimal->value)) {
221 m_minimal = heapNode;
222 }
223
224 return heapNode;
225}
226
227template<typename T, typename C>
229 // Special case for tree with only one node.
230 if (m_knot->next->next == m_knot && m_knot->next->child == nullptr) {
231 m_knot->prev = m_knot->next = m_knot;
232 delete m_minimal;
233 m_minimal = nullptr;
234 return;
235 }
236
237 remove();
238 compress();
239
240 // Find new minimal node in compressed tree list.
241 m_minimal = m_knot->next;
242 for (auto it = m_knot->next->next; it != m_knot; it = it->next) {
243 if (this->comparator()(it->value, m_minimal->value)) {
244 m_minimal = it;
245 }
246 }
247}
248
249template<typename T, typename C>
251 heapNode->value = value;
252 if (this->comparator()(heapNode->value, m_minimal->value)) {
253 m_minimal = heapNode;
254 }
255
256 restore(heapNode);
257}
258
259template<typename T, typename C>
261 if (other.m_minimal == nullptr) {
262 return;
263 }
264
265 FibonacciHeapNode<T>* next = other.m_knot->next;
266 detach(other.m_knot);
267 merge(next);
268
269 if (this->comparator()(other.m_minimal->value, m_minimal->value)) {
270 m_minimal = other.m_minimal;
271 }
272 other.m_minimal = nullptr;
273}
274
275template<typename T, typename C>
277 if (m_minimal->child) {
278 FibonacciHeapNode<T>* it = m_minimal->child;
279 do {
280 FibonacciHeapNode<T>* next = it->next;
281 it->parent = nullptr;
282 splice(m_knot, it);
283
284 it = next;
285 } while (it != m_minimal->child);
286 }
287 detach(m_minimal);
288 delete m_minimal;
289}
290
291template<typename T, typename C>
293 size_t maxr = 0;
294
295 for (auto it = m_knot->next; it != m_knot;) {
296 FibonacciHeapNode<T>* next = it->next;
297
298 size_t r = it->rank;
299 maxr = std::max(r, maxr);
300 while (m_ranked[r]) {
301 if (this->comparator()(m_ranked[r]->value, it->value)) {
302 link(m_ranked[r], it);
303 it = m_ranked[r];
304 } else {
305 link(it, m_ranked[r]);
306 }
307 m_ranked[r] = nullptr;
308 r++;
309 maxr = std::max(maxr, r);
310 }
311 m_ranked[r] = it;
312
313 it = next;
314 }
315
316 for (size_t i = 0; i <= maxr; i++) {
317 m_ranked[i] = nullptr;
318 }
319}
320
321template<typename T, typename C>
323 child->marked = false;
324 child->parent = root;
325 root->rank++;
326
327 if (root->child) {
328 splice(root->child, child);
329 } else {
330 detach(child);
331 root->child = child;
332 }
333}
334
335template<typename T, typename C>
337 heapNode->prev->next = heapNode->next;
338 heapNode->next->prev = heapNode->prev;
339 heapNode->next = heapNode;
340 heapNode->prev = heapNode;
341}
342
343template<typename T, typename C>
345 m_knot->next->prev = other->prev;
346 other->prev->next = m_knot->next;
347 m_knot->next = other;
348 other->prev = m_knot;
349}
350
351template<typename T, typename C>
353 detach(heapNode);
354 target->next->prev = heapNode;
355 heapNode->next = target->next;
356 target->next = heapNode;
357 heapNode->prev = target;
358}
359
360template<typename T, typename C>
362 for (;;) {
363 FibonacciHeapNode<T>* parent = heapNode->parent;
364 if (parent == nullptr) {
365 return;
366 }
367
368 // We need to make sure parent has valid children after the splice.
369 parent->rank--;
370 if (parent->rank == 0) {
371 parent->child = nullptr;
372 } else if (parent->child == heapNode) {
373 parent->child = heapNode->next;
374 }
375
376 heapNode->parent = nullptr;
377 splice(m_knot, heapNode);
378
379 // If parent is unmarked we can stop cut cascade.
380 if (!parent->marked) {
381 parent->marked = true;
382 return;
383 }
384
385 heapNode = parent;
386 }
387}
388
389}
Interface for heap implementations.
Fibonacci heap implementation.
virtual ~FibonacciHeap()
Destructs the heap.
void merge(FibonacciHeap< T, C > &other) override
Merges in values of other heap.
void detach(FibonacciHeapNode< T > *heapNode)
Detaches given heapNode from its list and makes it self-circulate.
void compress()
Reduces number of trees inside a heap by linking ones with same degree.
std::array< FibonacciHeapNode< T > *, sizeof(size_t) *8 > m_ranked
Used to compress trees.
void link(FibonacciHeapNode< T > *root, FibonacciHeapNode< T > *child)
Makes child node a child of root node.
void splice(FibonacciHeapNode< T > *target, FibonacciHeapNode< T > *heapNode)
Moves heapNode from its list to the target list.
void decrease(FibonacciHeapNode< T > *heapNode, const T &value) override
Decreases value of the given heapNode to value.
FibonacciHeapNode< T > * m_knot
Used for efficient tree list manipulation.
FibonacciHeapNode< T > * m_minimal
Handle to the tree with lowest root priority.
void release(FibonacciHeapNode< T > *heapNode)
Recursively releases memory starting at heapNode.
void restore(FibonacciHeapNode< T > *heapNode)
Restores heap ordering in heapNode by making (cascade) cut.
void pop() override
Removes the top element from the heap.
void remove()
Removes minimal tree and moves its children to tree list.
const T & value(FibonacciHeapNode< T > *heapNode) const override
Returns the value of the node.
FibonacciHeap(const C &cmp=C(), int initialSize=-1)
Creates empty Fibonacci heap.
const T & top() const override
Returns reference to the top element in the heap.
FibonacciHeapNode< T > * push(const T &value) override
Inserts a new node with given value into a heap.
Common interface for all heap classes.
Definition HeapBase.h:50
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:41
int r[]
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.
Fibonacci heap node.
bool marked
Indicates whether node is marked or not.
FibonacciHeapNode< T > * child
First child of the node.
FibonacciHeapNode(const T &nodeValue)
Creates heap node with a given nodeValue.
size_t rank
Determines rank of a node.
FibonacciHeapNode< T > * parent
Parent of the node.
FibonacciHeapNode< T > * next
Next sibling of the node.
T value
Value contained in the node.
FibonacciHeapNode()
Creates empty root node.
FibonacciHeapNode< T > * prev
Previous sibling of the node.