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
34#include <ogdf/basic/basic.h>
36
37#include <algorithm>
38#include <array>
39#include <cstddef>
40#include <functional>
41
42namespace ogdf {
43
44
46template<typename T>
48 template<typename, typename>
49 friend class FibonacciHeap;
50
51protected:
53
54 size_t rank;
55 bool marked;
56
61
64 : rank(0), marked(false), parent(nullptr), child(nullptr), prev(this), next(this) { }
65
67 explicit FibonacciHeapNode(const T& nodeValue)
68 : value(nodeValue)
69 , rank(0)
70 , marked(false)
71 , parent(nullptr)
72 , child(nullptr)
73 , prev(this)
74 , next(this) { }
75};
76
78
88template<typename T, typename C = std::less<T>>
89class FibonacciHeap : public HeapBase<FibonacciHeap<T, C>, FibonacciHeapNode<T>, T, C> {
91
92public:
99 explicit FibonacciHeap(const C& cmp = C(), int initialSize = -1);
100
107 virtual ~FibonacciHeap();
108
110 const T& top() const override;
111
118 FibonacciHeapNode<T>* push(const T& value) override;
119
125 void pop() override;
126
136 void decrease(FibonacciHeapNode<T>* heapNode, const T& value) override;
137
145 void merge(FibonacciHeap<T, C>& other) override;
146
153 const T& value(FibonacciHeapNode<T>* heapNode) const override { return heapNode->value; }
154
155private:
160
162 std::array<FibonacciHeapNode<T>*, sizeof(size_t) * 8> m_ranked;
163
165 void remove();
167 void compress();
168
172 void detach(FibonacciHeapNode<T>* heapNode);
174 void merge(FibonacciHeapNode<T>* other);
176 void splice(FibonacciHeapNode<T>* target, FibonacciHeapNode<T>* heapNode);
178 void restore(FibonacciHeapNode<T>* heapNode);
179
181 void release(FibonacciHeapNode<T>* heapNode);
182};
183
184template<typename T, typename C>
185FibonacciHeap<T, C>::FibonacciHeap(const C& cmp, int /* unused parameter */)
186 : base_type(cmp), m_minimal(nullptr), m_knot(new FibonacciHeapNode<T>()) {
187 m_ranked.fill(nullptr);
188}
189
190template<typename T, typename C>
192 release(m_knot);
193}
194
195template<typename T, typename C>
197 if (heapNode == nullptr) {
198 return;
199 }
200
201 FibonacciHeapNode<T>* end = heapNode;
202 do {
203 release(heapNode->child);
204
205 FibonacciHeapNode<T>* next = heapNode->next;
206 delete heapNode;
207 heapNode = next;
208 } while (heapNode != end);
209}
210
211template<typename T, typename C>
212inline const T& FibonacciHeap<T, C>::top() const {
213 OGDF_ASSERT(m_minimal != nullptr);
214 return m_minimal->value;
215}
216
217template<typename T, typename C>
219 FibonacciHeapNode<T>* heapNode = new FibonacciHeapNode<T>(value);
220 splice(m_knot, heapNode);
221
222 if (m_minimal == nullptr || this->comparator()(heapNode->value, m_minimal->value)) {
223 m_minimal = heapNode;
224 }
225
226 return heapNode;
227}
228
229template<typename T, typename C>
231 // Special case for tree with only one node.
232 if (m_knot->next->next == m_knot && m_knot->next->child == nullptr) {
233 m_knot->prev = m_knot->next = m_knot;
234 delete m_minimal;
235 m_minimal = nullptr;
236 return;
237 }
238
239 remove();
240 compress();
241
242 // Find new minimal node in compressed tree list.
243 m_minimal = m_knot->next;
244 for (auto it = m_knot->next->next; it != m_knot; it = it->next) {
245 if (this->comparator()(it->value, m_minimal->value)) {
246 m_minimal = it;
247 }
248 }
249}
250
251template<typename T, typename C>
253 heapNode->value = value;
254 if (this->comparator()(heapNode->value, m_minimal->value)) {
255 m_minimal = heapNode;
256 }
257
258 restore(heapNode);
259}
260
261template<typename T, typename C>
263 if (other.m_minimal == nullptr) {
264 return;
265 }
266
267 FibonacciHeapNode<T>* next = other.m_knot->next;
268 detach(other.m_knot);
269 merge(next);
270
271 if (this->comparator()(other.m_minimal->value, m_minimal->value)) {
272 m_minimal = other.m_minimal;
273 }
274 other.m_minimal = nullptr;
275}
276
277template<typename T, typename C>
279 if (m_minimal->child) {
280 FibonacciHeapNode<T>* it = m_minimal->child;
281 do {
282 FibonacciHeapNode<T>* next = it->next;
283 it->parent = nullptr;
284 splice(m_knot, it);
285
286 it = next;
287 } while (it != m_minimal->child);
288 }
289 detach(m_minimal);
290 delete m_minimal;
291}
292
293template<typename T, typename C>
295 size_t maxr = 0;
296
297 for (auto it = m_knot->next; it != m_knot;) {
298 FibonacciHeapNode<T>* next = it->next;
299
300 size_t r = it->rank;
301 maxr = std::max(r, maxr);
302 while (m_ranked[r]) {
303 if (this->comparator()(m_ranked[r]->value, it->value)) {
304 link(m_ranked[r], it);
305 it = m_ranked[r];
306 } else {
307 link(it, m_ranked[r]);
308 }
309 m_ranked[r] = nullptr;
310 r++;
311 maxr = std::max(maxr, r);
312 }
313 m_ranked[r] = it;
314
315 it = next;
316 }
317
318 for (size_t i = 0; i <= maxr; i++) {
319 m_ranked[i] = nullptr;
320 }
321}
322
323template<typename T, typename C>
325 child->marked = false;
326 child->parent = root;
327 root->rank++;
328
329 if (root->child) {
330 splice(root->child, child);
331 } else {
332 detach(child);
333 root->child = child;
334 }
335}
336
337template<typename T, typename C>
339 heapNode->prev->next = heapNode->next;
340 heapNode->next->prev = heapNode->prev;
341 heapNode->next = heapNode;
342 heapNode->prev = heapNode;
343}
344
345template<typename T, typename C>
347 m_knot->next->prev = other->prev;
348 other->prev->next = m_knot->next;
349 m_knot->next = other;
350 other->prev = m_knot;
351}
352
353template<typename T, typename C>
355 detach(heapNode);
356 target->next->prev = heapNode;
357 heapNode->next = target->next;
358 target->next = heapNode;
359 heapNode->prev = target;
360}
361
362template<typename T, typename C>
364 for (;;) {
365 FibonacciHeapNode<T>* parent = heapNode->parent;
366 if (parent == nullptr) {
367 return;
368 }
369
370 // We need to make sure parent has valid children after the splice.
371 parent->rank--;
372 if (parent->rank == 0) {
373 parent->child = nullptr;
374 } else if (parent->child == heapNode) {
375 parent->child = heapNode->next;
376 }
377
378 heapNode->parent = nullptr;
379 splice(m_knot, heapNode);
380
381 // If parent is unmarked we can stop cut cascade.
382 if (!parent->marked) {
383 parent->marked = true;
384 return;
385 }
386
387 heapNode = parent;
388 }
389}
390
391}
Interface for heap implementations.
Basic declarations, included by all source files.
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:48
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:52
The namespace for all OGDF objects.
HypergraphRegistry< HypernodeElement >::iterator end(const HypergraphRegistry< HypernodeElement > &self)
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.