Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

BinomialHeap.h
Go to the documentation of this file.
1 
32 #pragma once
33 
35 
36 #include <functional>
37 #include <utility>
38 
39 namespace ogdf {
40 
41 
43 template<typename T>
45  template<typename, typename>
46  friend class BinomialHeap;
47 
48 protected:
49  T value;
50 
51  size_t rank;
52 
56 
58  explicit BinomialHeapNode(const T& nodeValue)
59  : value(nodeValue), rank(0), parent(nullptr), next(nullptr), child(nullptr) { }
60 };
61 
63 
72 template<typename T, typename C = std::less<T>>
73 class BinomialHeap : public HeapBase<BinomialHeap<T, C>, BinomialHeapNode<T>, T, C> {
75 
76 public:
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 
139 private:
141 
145  void merge(BinomialHeapNode<T>* other);
146 
148  static void link(BinomialHeapNode<T>* parent, BinomialHeapNode<T>* child);
149 
151  static void release(BinomialHeapNode<T>* heapNode);
152 };
153 
154 template<typename T, typename C>
155 BinomialHeap<T, C>::BinomialHeap(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>
166  while (heapNode != nullptr) {
167  release(heapNode->child);
168 
169  BinomialHeapNode<T>* next = heapNode->next;
170  delete heapNode;
171  heapNode = next;
172  }
173 }
174 
175 template<typename T, typename C>
176 inline 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 
187 template<typename T, typename C>
189  BinomialHeapNode<T>* heapNode = new BinomialHeapNode<T>(value);
190 
191  merge(heapNode);
192  return heapNode;
193 }
194 
195 template<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 
225 template<typename T, typename C>
226 void BinomialHeap<T, C>::decrease(BinomialHeapNode<T>* heapNode, const T& value) {
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 
239 template<typename T, typename C>
241  merge(other.m_root);
242  other.m_root = nullptr;
243 }
244 
245 template<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) {
266  BinomialHeapNode<T>* nextB = b->next;
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 
280 template<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 
312 template<typename T, typename C>
314  child->next = parent->child;
315  child->parent = parent;
316  parent->child = child;
317  parent->rank++;
318 }
319 
320 }
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::BinomialHeap::value
const T & value(BinomialHeapNode< T > *heapNode) const override
Returns the value of the node.
Definition: BinomialHeap.h:137
ogdf::HeapBase
Common interface for all heap classes.
Definition: HeapBase.h:50
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:54
ogdf::BinomialHeap::decrease
void decrease(BinomialHeapNode< T > *heapNode, const T &value) override
Decreases value of the given heapNode to value.
Definition: BinomialHeap.h:226
ogdf::BinomialHeapNode::rank
size_t rank
Determines rank of a node.
Definition: BinomialHeap.h:51
ogdf::BinomialHeapNode::child
BinomialHeapNode< T > * child
First child of the node.
Definition: BinomialHeap.h:55
ogdf::BinomialHeap::top
const T & top() const override
Returns reference to the top element in the heap.
Definition: BinomialHeap.h:176
ogdf::BinomialHeap
Binomial heap implementation.
Definition: BinomialHeap.h:73
ogdf::BinomialHeap::release
static void release(BinomialHeapNode< T > *heapNode)
Releases memory occupied by list of heaps given as heapNode.
Definition: BinomialHeap.h:165
ogdf::BinomialHeapNode
Binomial heap node.
Definition: BinomialHeap.h:44
ogdf::BinomialHeap::push
BinomialHeapNode< T > * push(const T &value) override
Inserts a new node with given value into a heap.
Definition: BinomialHeap.h:188
ogdf::BinomialHeap::join
BinomialHeapNode< T > * join(BinomialHeapNode< T > *a, BinomialHeapNode< T > *b)
Joins heap lists a and b into single list sorted by the ranks.
Definition: BinomialHeap.h:246
ogdf::BinomialHeap::m_root
BinomialHeapNode< T > * m_root
Root node of the heap.
Definition: BinomialHeap.h:140
ogdf::BinomialHeap::~BinomialHeap
virtual ~BinomialHeap()
Destructs the heap.
Definition: BinomialHeap.h:159
ogdf::BinomialHeap::BinomialHeap
BinomialHeap(const C &cmp=C(), int initialSize=-1)
Creates empty binomial heap.
Definition: BinomialHeap.h:155
ogdf::sync_plan::join
void join(Graph &G, node u, node v, sync_plan::PipeBij &bij, List< bool > *reverse_v=nullptr)
ogdf::BinomialHeapNode::value
T value
Value contained in the node.
Definition: BinomialHeap.h:49
HeapBase.h
Interface for heap implementations.
ogdf::BinomialHeapNode::BinomialHeapNode
BinomialHeapNode(const T &nodeValue)
Creates heap node with a given nodeValue.
Definition: BinomialHeap.h:58
ogdf::BinomialHeap::pop
void pop() override
Removes the top element from the heap.
Definition: BinomialHeap.h:196
ogdf::BinomialHeap::link
static void link(BinomialHeapNode< T > *parent, BinomialHeapNode< T > *child)
Makes child node a child of parent node.
Definition: BinomialHeap.h:313
ogdf::BinomialHeap::merge
void merge(BinomialHeap< T, C > &other) override
Merges in values of other heap.
Definition: BinomialHeap.h:240
ogdf::BinomialHeapNode::next
BinomialHeapNode< T > * next
Next sibling of the node.
Definition: BinomialHeap.h:54
ogdf::BinomialHeapNode::parent
BinomialHeapNode< T > * parent
Parent of the node.
Definition: BinomialHeap.h:53