Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

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 
40 namespace ogdf {
41 
42 
44 template<typename T>
46  template<typename, typename>
47  friend class FibonacciHeap;
48 
49 protected:
50  T value;
51 
52  size_t rank;
53  bool marked;
54 
59 
62  : rank(0), marked(false), parent(nullptr), child(nullptr), prev(this), next(this) { }
63 
65  explicit FibonacciHeapNode(const T& nodeValue)
66  : value(nodeValue)
67  , rank(0)
68  , marked(false)
69  , parent(nullptr)
70  , child(nullptr)
71  , prev(this)
72  , next(this) { }
73 };
74 
76 
86 template<typename T, typename C = std::less<T>>
87 class FibonacciHeap : public HeapBase<FibonacciHeap<T, C>, FibonacciHeapNode<T>, T, C> {
89 
90 public:
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 
153 private:
158 
160  std::array<FibonacciHeapNode<T>*, sizeof(size_t) * 8> m_ranked;
161 
163  void remove();
165  void compress();
166 
168  void link(FibonacciHeapNode<T>* root, FibonacciHeapNode<T>* child);
170  void detach(FibonacciHeapNode<T>* heapNode);
172  void merge(FibonacciHeapNode<T>* other);
174  void splice(FibonacciHeapNode<T>* target, FibonacciHeapNode<T>* heapNode);
176  void restore(FibonacciHeapNode<T>* heapNode);
177 
179  void release(FibonacciHeapNode<T>* heapNode);
180 };
181 
182 template<typename T, typename C>
183 FibonacciHeap<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 
188 template<typename T, typename C>
190  release(m_knot);
191 }
192 
193 template<typename T, typename C>
195  if (heapNode == nullptr) {
196  return;
197  }
198 
199  FibonacciHeapNode<T>* end = heapNode;
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 
209 template<typename T, typename C>
210 inline const T& FibonacciHeap<T, C>::top() const {
211  OGDF_ASSERT(m_minimal != nullptr);
212  return m_minimal->value;
213 }
214 
215 template<typename T, typename C>
217  FibonacciHeapNode<T>* heapNode = new FibonacciHeapNode<T>(value);
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 
227 template<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 
249 template<typename T, typename C>
250 void FibonacciHeap<T, C>::decrease(FibonacciHeapNode<T>* heapNode, const T& value) {
251  heapNode->value = value;
252  if (this->comparator()(heapNode->value, m_minimal->value)) {
253  m_minimal = heapNode;
254  }
255 
256  restore(heapNode);
257 }
258 
259 template<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 
275 template<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 
291 template<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 
321 template<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 
335 template<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 
343 template<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 
351 template<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 
360 template<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 }
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::FibonacciHeapNode::FibonacciHeapNode
FibonacciHeapNode(const T &nodeValue)
Creates heap node with a given nodeValue.
Definition: FibonacciHeap.h:65
ogdf::HeapBase
Common interface for all heap classes.
Definition: HeapBase.h:50
ogdf::FibonacciHeap::remove
void remove()
Removes minimal tree and moves its children to tree list.
Definition: FibonacciHeap.h:276
ogdf::FibonacciHeapNode::FibonacciHeapNode
FibonacciHeapNode()
Creates empty root node.
Definition: FibonacciHeap.h:61
ogdf::FibonacciHeapNode::marked
bool marked
Indicates whether node is marked or not.
Definition: FibonacciHeap.h:53
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
ogdf::FibonacciHeapNode::prev
FibonacciHeapNode< T > * prev
Previous sibling of the node.
Definition: FibonacciHeap.h:57
ogdf::FibonacciHeap::compress
void compress()
Reduces number of trees inside a heap by linking ones with same degree.
Definition: FibonacciHeap.h:292
ogdf::FibonacciHeap::link
void link(FibonacciHeapNode< T > *root, FibonacciHeapNode< T > *child)
Makes child node a child of root node.
Definition: FibonacciHeap.h:322
ogdf::FibonacciHeap::FibonacciHeap
FibonacciHeap(const C &cmp=C(), int initialSize=-1)
Creates empty Fibonacci heap.
Definition: FibonacciHeap.h:183
ogdf::FibonacciHeap::decrease
void decrease(FibonacciHeapNode< T > *heapNode, const T &value) override
Decreases value of the given heapNode to value.
Definition: FibonacciHeap.h:250
ogdf::FibonacciHeapNode::value
T value
Value contained in the node.
Definition: FibonacciHeap.h:50
ogdf::FibonacciHeap::value
const T & value(FibonacciHeapNode< T > *heapNode) const override
Returns the value of the node.
Definition: FibonacciHeap.h:151
ogdf::FibonacciHeap::restore
void restore(FibonacciHeapNode< T > *heapNode)
Restores heap ordering in heapNode by making (cascade) cut.
Definition: FibonacciHeap.h:361
ogdf::FibonacciHeap::m_minimal
FibonacciHeapNode< T > * m_minimal
Handle to the tree with lowest root priority.
Definition: FibonacciHeap.h:155
ogdf::FibonacciHeap::push
FibonacciHeapNode< T > * push(const T &value) override
Inserts a new node with given value into a heap.
Definition: FibonacciHeap.h:216
ogdf::FibonacciHeap::top
const T & top() const override
Returns reference to the top element in the heap.
Definition: FibonacciHeap.h:210
ogdf::FibonacciHeap::m_ranked
std::array< FibonacciHeapNode< T > *, sizeof(size_t) *8 > m_ranked
Used to compress trees.
Definition: FibonacciHeap.h:160
r
int r[]
Definition: hierarchical-ranking.cpp:8
ogdf::FibonacciHeap::release
void release(FibonacciHeapNode< T > *heapNode)
Recursively releases memory starting at heapNode.
Definition: FibonacciHeap.h:194
ogdf::FibonacciHeapNode
Fibonacci heap node.
Definition: FibonacciHeap.h:45
ogdf::FibonacciHeapNode::next
FibonacciHeapNode< T > * next
Next sibling of the node.
Definition: FibonacciHeap.h:58
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:336
ogdf::FibonacciHeapNode::parent
FibonacciHeapNode< T > * parent
Parent of the node.
Definition: FibonacciHeap.h:55
ogdf::FibonacciHeap::merge
void merge(FibonacciHeap< T, C > &other) override
Merges in values of other heap.
Definition: FibonacciHeap.h:260
ogdf::FibonacciHeap::m_knot
FibonacciHeapNode< T > * m_knot
Used for efficient tree list manipulation.
Definition: FibonacciHeap.h:157
ogdf::end
HypergraphRegistry< HypernodeElement >::iterator end(const HypergraphRegistry< HypernodeElement > &self)
ogdf::FibonacciHeap
Fibonacci heap implementation.
Definition: FibonacciHeap.h:87
ogdf::FibonacciHeapNode::rank
size_t rank
Determines rank of a node.
Definition: FibonacciHeap.h:52
ogdf::FibonacciHeap::~FibonacciHeap
virtual ~FibonacciHeap()
Destructs the heap.
Definition: FibonacciHeap.h:189
ogdf::FibonacciHeap::pop
void pop() override
Removes the top element from the heap.
Definition: FibonacciHeap.h:228
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:56
ogdf::FibonacciHeap::splice
void splice(FibonacciHeapNode< T > *target, FibonacciHeapNode< T > *heapNode)
Moves heapNode from its list to the target list.
Definition: FibonacciHeap.h:352