Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

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