Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

PairingHeap.h
Go to the documentation of this file.
1 
32 #pragma once
33 
34 #include <ogdf/basic/basic.h>
36 
37 #include <cstddef>
38 
39 namespace ogdf {
40 
41 
43 template<typename T>
45  template<typename, typename>
46  friend class PairingHeap;
47 
48 protected:
49  T value;
50 
54 
56  explicit PairingHeapNode(const T& valueOfNode)
57  : value(valueOfNode), prev(nullptr), next(nullptr), child(nullptr) { }
58 };
59 
61 
70 template<typename T, typename C>
71 class PairingHeap : public HeapBase<PairingHeap<T, C>, PairingHeapNode<T>, T, C> {
73 
74 public:
81  explicit PairingHeap(const C& cmp = C(), int initialSize = -1);
82 
89  virtual ~PairingHeap();
90 
92  const T& top() const override;
93 
100  PairingHeapNode<T>* push(const T& value) override;
101 
107  void pop() override;
108 
118  void decrease(PairingHeapNode<T>* heapNode, const T& value) override;
119 
127  void merge(PairingHeap<T, C>& other) override;
128 
135  const T& value(PairingHeapNode<T>* heapNode) const override { return heapNode->value; }
136 
137 private:
139 
144 
146  static void link(PairingHeapNode<T>* parent, PairingHeapNode<T>* child);
148  static void unlink(PairingHeapNode<T>* heapNode);
149 
151  static void release(PairingHeapNode<T>* heapNode);
152 };
153 
154 template<typename T, typename C>
155 PairingHeap<T, C>::PairingHeap(const C& cmp, int /* unused parameter */)
156  : base_type(cmp), m_root(nullptr) { }
157 
158 template<typename T, typename C>
160  release(m_root);
161  m_root = nullptr;
162 }
163 
164 template<typename T, typename C>
165 inline const T& PairingHeap<T, C>::top() const {
166  OGDF_ASSERT(m_root != nullptr);
167  return m_root->value;
168 }
169 
170 template<typename T, typename C>
172  PairingHeapNode<T>* heapNode = new PairingHeapNode<T>(value);
173 
174  m_root = m_root == nullptr ? heapNode : merge(m_root, heapNode);
175  return heapNode;
176 }
177 
178 template<typename T, typename C>
180  PairingHeapNode<T>* children = m_root->child;
181  delete m_root;
182 
183  m_root = pair(children);
184 }
185 
186 template<typename T, typename C>
187 void PairingHeap<T, C>::decrease(PairingHeapNode<T>* heapNode, const T& value) {
188  heapNode->value = value;
189  if (heapNode->prev != nullptr) {
190  unlink(heapNode);
191  m_root = merge(m_root, heapNode);
192  }
193 }
194 
195 template<typename T, typename C>
197  m_root = merge(m_root, other.m_root);
198  other.m_root = nullptr;
199 }
200 
201 template<typename T, typename C>
203  if (heapNode == nullptr) {
204  return nullptr;
205  }
206 
207  /*
208  * We move towards the end of list counting elements along the way. We do
209  * this for two reasons: to know whether the list has even or odd number of
210  * elements and for possible speed up of going-back through the list (loop
211  * unrolling is not applicable for iterators but works for integers).
212  */
213  size_t children = 1;
214  PairingHeapNode<T>* it = heapNode;
215  while (it->next != nullptr) {
216  it = it->next;
217  children++;
218  }
219 
220  PairingHeapNode<T>* result;
221 
222  if (children % 2 == 1) {
223  PairingHeapNode<T>* a = it;
224  it = it->prev;
225  a->prev = a->next = nullptr;
226  result = a;
227  } else {
228  PairingHeapNode<T>*a = it, *b = it->prev;
229  it = it->prev->prev;
230  a->prev = a->next = b->prev = b->next = nullptr;
231  result = merge(a, b);
232  }
233 
234  for (size_t i = 0; i < (children - 1) / 2; i++) {
235  PairingHeapNode<T>*a = it, *b = it->prev;
236  it = it->prev->prev;
237  a->prev = a->next = b->prev = b->next = nullptr;
238  result = merge(merge(a, b), result);
239  }
240 
241  return result;
242 }
243 
244 template<typename T, typename C>
246  if (a == nullptr) {
247  return b;
248  }
249  if (b == nullptr) {
250  return a;
251  }
252  if (this->comparator()(a->value, b->value)) {
253  link(a, b);
254  return a;
255  } else {
256  link(b, a);
257  return b;
258  }
259 }
260 
261 template<typename T, typename C>
263  if (root->child != nullptr) {
264  child->next = root->child;
265  root->child->prev = child;
266  }
267  child->prev = root;
268  root->child = child;
269 }
270 
271 template<typename T, typename C>
273  if (heapNode->prev->child == heapNode) {
274  heapNode->prev->child = heapNode->next;
275  } else {
276  heapNode->prev->next = heapNode->next;
277  }
278  if (heapNode->next != nullptr) {
279  heapNode->next->prev = heapNode->prev;
280  }
281  heapNode->prev = nullptr;
282  heapNode->next = nullptr;
283 }
284 
285 template<typename T, typename C>
287  /*
288  * Recursive version of this function is infinitely prettier than that
289  * abomination. Please, make it prettier if you can.
290  */
291  PairingHeapNode<T>* it = heapNode;
292 
293  if (it == nullptr) {
294  return;
295  }
296 
297  for (;;) {
298  // Slide down as long as possible.
299  if (it->child != nullptr) {
300  it = it->child;
301  continue;
302  }
303  if (it->next != nullptr) {
304  it = it->next;
305  continue;
306  }
307 
308  // Climb up until you find first non-visited node.
309  for (;;) {
310  PairingHeapNode<T>*curr = it, *prev = it->prev;
311  delete it;
312 
313  if (prev == nullptr) {
314  return;
315  }
316  if (curr == prev->child && prev->next != nullptr) {
317  it = prev->next;
318  break;
319  } else {
320  it = prev;
321  }
322  }
323  }
324 }
325 
326 }
ogdf::PairingHeap::pop
void pop() override
Removes the top element from the heap.
Definition: PairingHeap.h:179
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
ogdf::HeapBase
Common interface for all heap classes.
Definition: HeapBase.h:48
ogdf::PairingHeapNode::child
PairingHeapNode< T > * child
First child of the node.
Definition: PairingHeap.h:53
ogdf::PairingHeap::~PairingHeap
virtual ~PairingHeap()
Destructs pairing heap.
Definition: PairingHeap.h:159
ogdf::PairingHeap::link
static void link(PairingHeapNode< T > *parent, PairingHeapNode< T > *child)
Makes child node a child of parent node.
Definition: PairingHeap.h:262
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
ogdf::PairingHeap::pair
PairingHeapNode< T > * pair(PairingHeapNode< T > *heapNode)
Pairs list of heaps given as heapNode. Returns resulting list.
Definition: PairingHeap.h:202
ogdf::PairingHeap::PairingHeap
PairingHeap(const C &cmp=C(), int initialSize=-1)
Creates empty pairing heap.
Definition: PairingHeap.h:155
ogdf::PairingHeap::decrease
void decrease(PairingHeapNode< T > *heapNode, const T &value) override
Decreases value of the given heapNode to value.
Definition: PairingHeap.h:187
ogdf::PairingHeapNode
Pairing heap node.
Definition: PairingHeap.h:44
ogdf::PairingHeapNode::prev
PairingHeapNode< T > * prev
Previous sibling of the node or parent.
Definition: PairingHeap.h:51
ogdf::PairingHeap::merge
void merge(PairingHeap< T, C > &other) override
Merges in values of other heap.
Definition: PairingHeap.h:196
ogdf::PairingHeap
Pairing heap implementation.
Definition: PairingHeap.h:71
ogdf::PairingHeap::value
const T & value(PairingHeapNode< T > *heapNode) const override
Returns the value of the node.
Definition: PairingHeap.h:135
ogdf::PairingHeap::push
PairingHeapNode< T > * push(const T &value) override
Inserts a new node with given value into a heap.
Definition: PairingHeap.h:171
HeapBase.h
Interface for heap implementations.
ogdf::PairingHeapNode::next
PairingHeapNode< T > * next
Next sibling of the node.
Definition: PairingHeap.h:52
basic.h
Basic declarations, included by all source files.
ogdf::PairingHeap::top
const T & top() const override
Returns reference to the top element in the heap.
Definition: PairingHeap.h:165
ogdf::PairingHeapNode::PairingHeapNode
PairingHeapNode(const T &valueOfNode)
Creates heap node with a given valueOfNode.
Definition: PairingHeap.h:56
ogdf::PairingHeapNode::value
T value
Value contained in the node.
Definition: PairingHeap.h:49
ogdf::PairingHeap::m_root
PairingHeapNode< T > * m_root
Root node of the heap.
Definition: PairingHeap.h:138
ogdf::PairingHeap::unlink
static void unlink(PairingHeapNode< T > *heapNode)
Removes heapNode from its parent children list.
Definition: PairingHeap.h:272
ogdf::PairingHeap::release
static void release(PairingHeapNode< T > *heapNode)
Releases memory occupied by list of heaps given as heapNode.
Definition: PairingHeap.h:286