Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
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
39namespace ogdf {
40
41
43template<typename T>
45 template<typename, typename>
46 friend class PairingHeap;
47
48protected:
50
54
56 explicit PairingHeapNode(const T& valueOfNode)
57 : value(valueOfNode), prev(nullptr), next(nullptr), child(nullptr) { }
58};
59
61
70template<typename T, typename C>
71class PairingHeap : public HeapBase<PairingHeap<T, C>, PairingHeapNode<T>, T, C> {
73
74public:
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
137private:
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
154template<typename T, typename C>
155PairingHeap<T, C>::PairingHeap(const C& cmp, int /* unused parameter */)
156 : base_type(cmp), m_root(nullptr) { }
157
158template<typename T, typename C>
160 release(m_root);
161 m_root = nullptr;
162}
163
164template<typename T, typename C>
165inline const T& PairingHeap<T, C>::top() const {
166 OGDF_ASSERT(m_root != nullptr);
167 return m_root->value;
168}
169
170template<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
178template<typename T, typename C>
180 PairingHeapNode<T>* children = m_root->child;
181 delete m_root;
182
183 m_root = pair(children);
184}
185
186template<typename T, typename C>
187void 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
195template<typename T, typename C>
197 m_root = merge(m_root, other.m_root);
198 other.m_root = nullptr;
199}
200
201template<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
244template<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
261template<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
271template<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
285template<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}
Interface for heap implementations.
Basic declarations, included by all source files.
Common interface for all heap classes.
Definition HeapBase.h:48
Pairing heap implementation.
Definition PairingHeap.h:71
static void release(PairingHeapNode< T > *heapNode)
Releases memory occupied by list of heaps given as heapNode.
static void link(PairingHeapNode< T > *parent, PairingHeapNode< T > *child)
Makes child node a child of parent node.
PairingHeapNode< T > * m_root
Root node of the heap.
void merge(PairingHeap< T, C > &other) override
Merges in values of other heap.
PairingHeapNode< T > * push(const T &value) override
Inserts a new node with given value into a heap.
const T & top() const override
Returns reference to the top element in the heap.
PairingHeapNode< T > * pair(PairingHeapNode< T > *heapNode)
Pairs list of heaps given as heapNode. Returns resulting list.
void pop() override
Removes the top element from the heap.
PairingHeap(const C &cmp=C(), int initialSize=-1)
Creates empty pairing heap.
virtual ~PairingHeap()
Destructs pairing heap.
static void unlink(PairingHeapNode< T > *heapNode)
Removes heapNode from its parent children list.
void decrease(PairingHeapNode< T > *heapNode, const T &value) override
Decreases value of the given heapNode to value.
const T & value(PairingHeapNode< T > *heapNode) const override
Returns the value of the node.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:52
The namespace for all OGDF objects.
Pairing heap node.
Definition PairingHeap.h:44
PairingHeapNode(const T &valueOfNode)
Creates heap node with a given valueOfNode.
Definition PairingHeap.h:56
PairingHeapNode< T > * next
Next sibling of the node.
Definition PairingHeap.h:52
PairingHeapNode< T > * child
First child of the node.
Definition PairingHeap.h:53
T value
Value contained in the node.
Definition PairingHeap.h:49
PairingHeapNode< T > * prev
Previous sibling of the node or parent.
Definition PairingHeap.h:51