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
35
36#include <functional>
37#include <utility>
38
39namespace ogdf {
40
41
43template<typename T>
45 template<typename, typename>
46 friend class BinomialHeap;
47
48protected:
50
51 size_t rank;
52
56
60};
61
63
72template<typename T, typename C = std::less<T>>
73class BinomialHeap : public HeapBase<BinomialHeap<T, C>, BinomialHeapNode<T>, T, C> {
75
76public:
83 explicit BinomialHeap(const C& cmp = C(), int initialSize = -1);
84
91 virtual ~BinomialHeap();
92
94 const T& top() const override;
95
102 BinomialHeapNode<T>* push(const T& value) override;
103
109 void pop() override;
110
120 void decrease(BinomialHeapNode<T>* heapNode, const T& value) override;
121
129 void merge(BinomialHeap<T, C>& other) override;
130
137 const T& value(BinomialHeapNode<T>* heapNode) const override { return heapNode->value; }
138
139private:
141
146
148 static void link(BinomialHeapNode<T>* parent, BinomialHeapNode<T>* child);
149
152};
153
154template<typename T, typename C>
155BinomialHeap<T, C>::BinomialHeap(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>
166 while (heapNode != nullptr) {
167 release(heapNode->child);
168
169 BinomialHeapNode<T>* next = heapNode->next;
170 delete heapNode;
171 heapNode = next;
172 }
173}
174
175template<typename T, typename C>
176inline const T& BinomialHeap<T, C>::top() const {
177 BinomialHeapNode<T>* min = m_root;
178 for (BinomialHeapNode<T>* it = m_root->next; it != nullptr; it = it->next) {
179 if (this->comparator()(it->value, min->value)) {
180 min = it;
181 }
182 }
183
184 return min->value;
185}
186
187template<typename T, typename C>
190
191 merge(heapNode);
192 return heapNode;
193}
194
195template<typename T, typename C>
197 BinomialHeapNode<T>*curr = m_root, *min = m_root, *minPrev = nullptr;
198
199 while (curr->next != nullptr) {
200 if (this->comparator()(curr->next->value, min->value)) {
201 min = curr->next;
202 minPrev = curr;
203 }
204 curr = curr->next;
205 }
206
207 if (min == m_root) {
208 m_root = min->next;
209 } else {
210 minPrev->next = min->next;
211 }
212
213 // Children list has to be reversed before it can be merged.
214 BinomialHeapNode<T>*reversed = nullptr, *child = min->child;
215 while (child != nullptr) {
216 BinomialHeapNode<T>* next = child->next;
217 child->next = reversed;
218 reversed = child;
219 child = next;
220 }
221 merge(reversed);
222 delete min;
223}
224
225template<typename T, typename C>
227 // BinomialHeap::decrease is not supported
228 OGDF_ASSERT(false);
229
230 heapNode->value = value;
231
232 while (heapNode->parent != nullptr
233 && this->comparator()(heapNode->value, heapNode->parent->value)) {
234 std::swap(heapNode->value, heapNode->parent->value);
235 heapNode = heapNode->parent;
236 }
237}
238
239template<typename T, typename C>
241 merge(other.m_root);
242 other.m_root = nullptr;
243}
244
245template<typename T, typename C>
247 if (a == nullptr) {
248 return b;
249 }
250 if (b == nullptr) {
251 return a;
252 }
253
254 if (b->rank < a->rank) {
255 std::swap(a, b);
256 }
257
258 BinomialHeapNode<T>* head = a;
259 while (b != nullptr) {
260 if (a->next == nullptr) {
261 a->next = b;
262 break;
263 }
264
265 if (b->rank < a->next->rank) {
267 b->next = a->next;
268 a->next = b;
269
270 a = b;
271 b = nextB;
272 } else {
273 a = a->next;
274 }
275 }
276
277 return head;
278}
279
280template<typename T, typename C>
282 m_root = join(m_root, other);
283 if (m_root == nullptr) {
284 return;
285 }
286
287 BinomialHeapNode<T>*prev = nullptr, *curr = m_root, *next = m_root->next;
288 while (next != nullptr) {
289 if (curr->rank != next->rank || (next->next != nullptr && next->next->rank == curr->rank)) {
290 prev = curr;
291 curr = next;
292 next = curr->next;
293 continue;
294 }
295
296 if (this->comparator()(curr->value, next->value)) {
297 curr->next = next->next;
298 link(curr, next);
299 } else if (prev == nullptr) {
300 m_root = next;
301 link(next, curr);
302 curr = next;
303 } else {
304 prev->next = next;
305 link(next, curr);
306 curr = next;
307 }
308 next = curr->next;
309 }
310}
311
312template<typename T, typename C>
314 child->next = parent->child;
315 child->parent = parent;
316 parent->child = child;
317 parent->rank++;
318}
319
320}
Interface for heap implementations.
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:50
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:41
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
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.