Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

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 
42 namespace ogdf {
43 
44 
46 template<typename T>
48  template<typename, typename>
49  friend class FibonacciHeap;
50 
51 protected:
52  T value;
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 
88 template<typename T, typename C = std::less<T>>
89 class FibonacciHeap : public HeapBase<FibonacciHeap<T, C>, FibonacciHeapNode<T>, T, C> {
91 
92 public:
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 
155 private:
160 
162  std::array<FibonacciHeapNode<T>*, sizeof(size_t) * 8> m_ranked;
163 
165  void remove();
167  void compress();
168 
170  void link(FibonacciHeapNode<T>* root, FibonacciHeapNode<T>* child);
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 
184 template<typename T, typename C>
185 FibonacciHeap<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 
190 template<typename T, typename C>
192  release(m_knot);
193 }
194 
195 template<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 
211 template<typename T, typename C>
212 inline const T& FibonacciHeap<T, C>::top() const {
213  OGDF_ASSERT(m_minimal != nullptr);
214  return m_minimal->value;
215 }
216 
217 template<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 
229 template<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 
251 template<typename T, typename C>
252 void FibonacciHeap<T, C>::decrease(FibonacciHeapNode<T>* heapNode, const T& value) {
253  heapNode->value = value;
254  if (this->comparator()(heapNode->value, m_minimal->value)) {
255  m_minimal = heapNode;
256  }
257 
258  restore(heapNode);
259 }
260 
261 template<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 
277 template<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 
293 template<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 
323 template<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 
337 template<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 
345 template<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 
353 template<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 
362 template<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 }
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
ogdf::FibonacciHeapNode::FibonacciHeapNode
FibonacciHeapNode(const T &nodeValue)
Creates heap node with a given nodeValue.
Definition: FibonacciHeap.h:67
ogdf::HeapBase
Common interface for all heap classes.
Definition: HeapBase.h:48
ogdf::FibonacciHeap::remove
void remove()
Removes minimal tree and moves its children to tree list.
Definition: FibonacciHeap.h:278
ogdf::FibonacciHeapNode::FibonacciHeapNode
FibonacciHeapNode()
Creates empty root node.
Definition: FibonacciHeap.h:63
ogdf::FibonacciHeapNode::marked
bool marked
Indicates whether node is marked or not.
Definition: FibonacciHeap.h:55
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
ogdf::FibonacciHeapNode::prev
FibonacciHeapNode< T > * prev
Previous sibling of the node.
Definition: FibonacciHeap.h:59
ogdf::FibonacciHeap::compress
void compress()
Reduces number of trees inside a heap by linking ones with same degree.
Definition: FibonacciHeap.h:294
ogdf::FibonacciHeap::link
void link(FibonacciHeapNode< T > *root, FibonacciHeapNode< T > *child)
Makes child node a child of root node.
Definition: FibonacciHeap.h:324
ogdf::FibonacciHeap::FibonacciHeap
FibonacciHeap(const C &cmp=C(), int initialSize=-1)
Creates empty Fibonacci heap.
Definition: FibonacciHeap.h:185
ogdf::FibonacciHeap::decrease
void decrease(FibonacciHeapNode< T > *heapNode, const T &value) override
Decreases value of the given heapNode to value.
Definition: FibonacciHeap.h:252
ogdf::FibonacciHeapNode::value
T value
Value contained in the node.
Definition: FibonacciHeap.h:52
ogdf::FibonacciHeap::value
const T & value(FibonacciHeapNode< T > *heapNode) const override
Returns the value of the node.
Definition: FibonacciHeap.h:153
ogdf::FibonacciHeap::restore
void restore(FibonacciHeapNode< T > *heapNode)
Restores heap ordering in heapNode by making (cascade) cut.
Definition: FibonacciHeap.h:363
ogdf::FibonacciHeap::m_minimal
FibonacciHeapNode< T > * m_minimal
Handle to the tree with lowest root priority.
Definition: FibonacciHeap.h:157
ogdf::FibonacciHeap::push
FibonacciHeapNode< T > * push(const T &value) override
Inserts a new node with given value into a heap.
Definition: FibonacciHeap.h:218
ogdf::FibonacciHeap::top
const T & top() const override
Returns reference to the top element in the heap.
Definition: FibonacciHeap.h:212
ogdf::FibonacciHeap::m_ranked
std::array< FibonacciHeapNode< T > *, sizeof(size_t) *8 > m_ranked
Used to compress trees.
Definition: FibonacciHeap.h:162
r
int r[]
Definition: hierarchical-ranking.cpp:13
ogdf::FibonacciHeap::release
void release(FibonacciHeapNode< T > *heapNode)
Recursively releases memory starting at heapNode.
Definition: FibonacciHeap.h:196
ogdf::FibonacciHeapNode
Fibonacci heap node.
Definition: FibonacciHeap.h:47
ogdf::FibonacciHeapNode::next
FibonacciHeapNode< T > * next
Next sibling of the node.
Definition: FibonacciHeap.h:60
HeapBase.h
Interface for heap implementations.
ogdf::FibonacciHeap::detach
void detach(FibonacciHeapNode< T > *heapNode)
Detaches given heapNode from its list and makes it self-circulate.
Definition: FibonacciHeap.h:338
ogdf::FibonacciHeapNode::parent
FibonacciHeapNode< T > * parent
Parent of the node.
Definition: FibonacciHeap.h:57
ogdf::FibonacciHeap::merge
void merge(FibonacciHeap< T, C > &other) override
Merges in values of other heap.
Definition: FibonacciHeap.h:262
ogdf::FibonacciHeap::m_knot
FibonacciHeapNode< T > * m_knot
Used for efficient tree list manipulation.
Definition: FibonacciHeap.h:159
basic.h
Basic declarations, included by all source files.
ogdf::end
HypergraphRegistry< HypernodeElement >::iterator end(const HypergraphRegistry< HypernodeElement > &self)
ogdf::FibonacciHeap
Fibonacci heap implementation.
Definition: FibonacciHeap.h:89
ogdf::FibonacciHeapNode::rank
size_t rank
Determines rank of a node.
Definition: FibonacciHeap.h:54
ogdf::FibonacciHeap::~FibonacciHeap
virtual ~FibonacciHeap()
Destructs the heap.
Definition: FibonacciHeap.h:191
ogdf::FibonacciHeap::pop
void pop() override
Removes the top element from the heap.
Definition: FibonacciHeap.h:230
Minisat::Internal::remove
static void remove(V &ts, const T &t)
Definition: Alg.h:36
ogdf::FibonacciHeapNode::child
FibonacciHeapNode< T > * child
First child of the node.
Definition: FibonacciHeap.h:58
ogdf::FibonacciHeap::splice
void splice(FibonacciHeapNode< T > *target, FibonacciHeapNode< T > *heapNode)
Moves heapNode from its list to the target list.
Definition: FibonacciHeap.h:354