Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
BinomialHeap.h
Go to the documentation of this file.
1
32#pragma once
33
34#include <ogdf/basic/basic.h>
36
37#include <cstddef>
38#include <functional>
39
40namespace ogdf {
41
42
44template<typename T>
46 template<typename, typename>
47 friend class BinomialHeap;
48
49protected:
51
52 size_t rank;
53
57
59 explicit BinomialHeapNode(const T& nodeValue)
60 : value(nodeValue), rank(0), parent(nullptr), next(nullptr), child(nullptr) { }
61};
62
64
73template<typename T, typename C = std::less<T>>
74class BinomialHeap : public HeapBase<BinomialHeap<T, C>, BinomialHeapNode<T>, T, C> {
76
77public:
84 explicit BinomialHeap(const C& cmp = C(), int initialSize = -1);
85
92 virtual ~BinomialHeap();
93
95 const T& top() const override;
96
103 BinomialHeapNode<T>* push(const T& value) override;
104
110 void pop() override;
111
121 void decrease(BinomialHeapNode<T>* heapNode, const T& value) override;
122
130 void merge(BinomialHeap<T, C>& other) override;
131
138 const T& value(BinomialHeapNode<T>* heapNode) const override { return heapNode->value; }
139
140private:
142
146 void merge(BinomialHeapNode<T>* other);
147
149 static void link(BinomialHeapNode<T>* parent, BinomialHeapNode<T>* child);
150
152 static void release(BinomialHeapNode<T>* heapNode);
153};
154
155template<typename T, typename C>
156BinomialHeap<T, C>::BinomialHeap(const C& cmp, int /* unused parameter */)
157 : base_type(cmp), m_root(nullptr) { }
158
159template<typename T, typename C>
161 release(m_root);
162 m_root = nullptr;
163}
164
165template<typename T, typename C>
167 while (heapNode != nullptr) {
168 release(heapNode->child);
169
170 BinomialHeapNode<T>* next = heapNode->next;
171 delete heapNode;
172 heapNode = next;
173 }
174}
175
176template<typename T, typename C>
177inline const T& BinomialHeap<T, C>::top() const {
178 BinomialHeapNode<T>* min = m_root;
179 for (BinomialHeapNode<T>* it = m_root->next; it != nullptr; it = it->next) {
180 if (this->comparator()(it->value, min->value)) {
181 min = it;
182 }
183 }
184
185 return min->value;
186}
187
188template<typename T, typename C>
190 BinomialHeapNode<T>* heapNode = new BinomialHeapNode<T>(value);
191
192 merge(heapNode);
193 return heapNode;
194}
195
196template<typename T, typename C>
198 BinomialHeapNode<T>*curr = m_root, *min = m_root, *minPrev = nullptr;
199
200 while (curr->next != nullptr) {
201 if (this->comparator()(curr->next->value, min->value)) {
202 min = curr->next;
203 minPrev = curr;
204 }
205 curr = curr->next;
206 }
207
208 if (min == m_root) {
209 m_root = min->next;
210 } else {
211 minPrev->next = min->next;
212 }
213
214 // Children list has to be reversed before it can be merged.
215 BinomialHeapNode<T>*reversed = nullptr, *child = min->child;
216 while (child != nullptr) {
217 BinomialHeapNode<T>* next = child->next;
218 child->next = reversed;
219 reversed = child;
220 child = next;
221 }
222 merge(reversed);
223 delete min;
224}
225
226template<typename T, typename C>
227void BinomialHeap<T, C>::decrease(BinomialHeapNode<T>* heapNode, const T& value) {
228 // BinomialHeap::decrease is not supported
229 OGDF_ASSERT(false);
230
231 heapNode->value = value;
232
233 while (heapNode->parent != nullptr
234 && this->comparator()(heapNode->value, heapNode->parent->value)) {
235 std::swap(heapNode->value, heapNode->parent->value);
236 heapNode = heapNode->parent;
237 }
238}
239
240template<typename T, typename C>
242 merge(other.m_root);
243 other.m_root = nullptr;
244}
245
246template<typename T, typename C>
248 if (a == nullptr) {
249 return b;
250 }
251 if (b == nullptr) {
252 return a;
253 }
254
255 if (b->rank < a->rank) {
256 std::swap(a, b);
257 }
258
259 BinomialHeapNode<T>* head = a;
260 while (b != nullptr) {
261 if (a->next == nullptr) {
262 a->next = b;
263 break;
264 }
265
266 if (b->rank < a->next->rank) {
267 BinomialHeapNode<T>* nextB = b->next;
268 b->next = a->next;
269 a->next = b;
270
271 a = b;
272 b = nextB;
273 } else {
274 a = a->next;
275 }
276 }
277
278 return head;
279}
280
281template<typename T, typename C>
283 m_root = join(m_root, other);
284 if (m_root == nullptr) {
285 return;
286 }
287
288 BinomialHeapNode<T>*prev = nullptr, *curr = m_root, *next = m_root->next;
289 while (next != nullptr) {
290 if (curr->rank != next->rank || (next->next != nullptr && next->next->rank == curr->rank)) {
291 prev = curr;
292 curr = next;
293 next = curr->next;
294 continue;
295 }
296
297 if (this->comparator()(curr->value, next->value)) {
298 curr->next = next->next;
299 link(curr, next);
300 } else if (prev == nullptr) {
301 m_root = next;
302 link(next, curr);
303 curr = next;
304 } else {
305 prev->next = next;
306 link(next, curr);
307 curr = next;
308 }
309 next = curr->next;
310 }
311}
312
313template<typename T, typename C>
315 child->next = parent->child;
316 child->parent = parent;
317 parent->child = child;
318 parent->rank++;
319}
320
321}
Interface for heap implementations.
Basic declarations, included by all source files.
Binomial heap implementation.
BinomialHeapNode< T > * m_root
Root node of the heap.
static void link(BinomialHeapNode< T > *parent, BinomialHeapNode< T > *child)
Makes child node a child of parent node.
virtual ~BinomialHeap()
Destructs the heap.
static void release(BinomialHeapNode< T > *heapNode)
Releases memory occupied by list of heaps given as heapNode.
BinomialHeapNode< T > * join(BinomialHeapNode< T > *a, BinomialHeapNode< T > *b)
Joins heap lists a and b into single list sorted by the ranks.
void pop() override
Removes the top element from the heap.
void merge(BinomialHeap< T, C > &other) override
Merges in values of other heap.
BinomialHeapNode< 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.
void decrease(BinomialHeapNode< T > *heapNode, const T &value) override
Decreases value of the given heapNode to value.
BinomialHeap(const C &cmp=C(), int initialSize=-1)
Creates empty binomial heap.
const T & value(BinomialHeapNode< T > *heapNode) const override
Returns the value of the node.
Common interface for all heap classes.
Definition HeapBase.h:48
void join(Graph &G1, const Graph &G2, NodeArray< node > &nodeMap, EdgeArray< edge > &edgeMap)
Computes the graph join of G1 and G2.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:52
The namespace for all OGDF objects.
Binomial heap node.
BinomialHeapNode< T > * child
First child of the node.
size_t rank
Determines rank of a node.
BinomialHeapNode< T > * parent
Parent of the node.
BinomialHeapNode(const T &nodeValue)
Creates heap node with a given nodeValue.
BinomialHeapNode< T > * next
Next sibling of the node.
T value
Value contained in the node.