Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

RadixHeap.h
Go to the documentation of this file.
1 
32 #pragma once
33 
34 #include <array>
35 #include <functional>
36 #include <utility>
37 #include <vector>
38 
39 namespace ogdf {
40 
41 
42 template<typename V, typename P>
44 public:
45  V value;
47 
50 
51  RadixHeapNode(const V& nodeValue, const P& nodePriority)
52  : value(nodeValue), priority(nodePriority), prev(nullptr), next(nullptr) { }
53 };
54 
56 
68 template<typename V, typename P>
69 class RadixHeap {
70 public:
72  RadixHeap();
73 
75  ~RadixHeap();
76 
77 
79 
84  RadixHeapNode<V, P>* push(const V& value, const P& priority);
85 
87 
92  V pop();
93 
95  std::size_t size() const { return m_size; }
96 
98  bool empty() const { return size() == 0; }
99 
100 private:
102  static constexpr std::size_t BITS = sizeof(P) * 8;
103 
104  std::size_t m_size;
105 
108  std::array<Bucket, BITS + 1> m_buckets;
109 
111  void insert(RadixHeapNode<V, P>* heapNode);
112 
114  template<typename T>
115  static std::size_t msbSet(T mask) {
116  std::size_t i = 0;
117  while (mask != 0) {
118  mask >>= 1;
119  i++;
120  }
121  return i;
122  }
123 
124 #ifdef __has_builtin
125 # if __has_builtin(__builtin_clz)
126  static std::size_t msbSet(unsigned int mask) {
127  return mask == 0 ? 0 : (BITS - __builtin_clz(mask));
128  }
129 
130  static std::size_t msbSet(unsigned long mask) {
131  return mask == 0 ? 0 : (BITS - __builtin_clzl(mask));
132  }
133 
134  static std::size_t msbSet(unsigned long long mask) {
135  return mask == 0 ? 0 : (BITS - __builtin_clzll(mask));
136  }
137 # endif
138 #endif
139 };
140 
141 template<typename V, typename P>
142 RadixHeap<V, P>::RadixHeap() : m_size(0), m_minimum(0), m_bucketMask(0) {
143  m_buckets.fill(nullptr);
144 }
145 
146 template<typename V, typename P>
148  for (Bucket& bucket : m_buckets) {
149  auto it = bucket;
150  while (it != nullptr) {
151  auto next = it->next;
152  delete it;
153  it = next;
154  }
155  }
156 }
157 
158 template<typename V, typename P>
159 RadixHeapNode<V, P>* RadixHeap<V, P>::push(const V& value, const P& priority) {
160  m_size++;
161 
162  RadixHeapNode<V, P>* heapNode = new RadixHeapNode<V, P>(value, priority);
163  insert(heapNode);
164  return heapNode;
165 }
166 
167 template<typename V, typename P>
169  m_size--;
170 
171  if (m_buckets[0] != nullptr) {
172  V result = std::move(m_buckets[0]->value);
173 
174  Bucket tmp = m_buckets[0]->next;
175  delete m_buckets[0];
176  m_buckets[0] = tmp;
177 
178  if (m_buckets[0] != nullptr) {
179  m_buckets[0]->prev = nullptr;
180  }
181  return result;
182  }
183 
184  std::size_t ind = BITS + 1 - msbSet(m_bucketMask);
185 
186  Bucket bucket = m_buckets[ind];
187  m_buckets[ind] = nullptr;
188  if (ind != 0) {
189  m_bucketMask ^= (P(1) << (8 * sizeof(P) - ind));
190  }
191 
192 
193  Bucket min = bucket;
194  for (Bucket it = bucket; it != nullptr; it = it->next) {
195  if (it->priority < min->priority) {
196  min = it;
197  }
198  }
199 
200  if (min->prev != nullptr) {
201  min->prev->next = min->next;
202  } else {
203  bucket = min->next;
204  }
205 
206  if (min->next != nullptr) {
207  min->next->prev = min->prev;
208  }
209 
210  V result = std::move(min->value);
211  m_minimum = std::move(min->priority);
212  delete min;
213 
214  while (bucket != nullptr) {
215  Bucket next = bucket->next;
216  bucket->prev = nullptr;
217  insert(bucket);
218 
219  bucket = next;
220  }
221 
222  return result;
223 }
224 
225 template<typename V, typename P>
227  std::size_t ind = msbSet(heapNode->priority ^ m_minimum);
228 
229  heapNode->next = m_buckets[ind];
230  if (m_buckets[ind] != nullptr) {
231  m_buckets[ind]->prev = heapNode;
232  }
233  m_buckets[ind] = heapNode;
234 
235  if (ind != 0) {
236  m_bucketMask |= (P(1) << (BITS - ind));
237  }
238 }
239 
240 }
ogdf
The namespace for all OGDF objects.
Definition: AugmentationModule.h:36
ogdf::RadixHeap::m_bucketMask
P m_bucketMask
Priority of the lowest element so far.
Definition: RadixHeap.h:107
ogdf::RadixHeap::m_minimum
P m_minimum
Number of elements.
Definition: RadixHeap.h:106
ogdf::RadixHeap::BITS
static constexpr std::size_t BITS
Definition: RadixHeap.h:102
ogdf::RadixHeap::msbSet
static std::size_t msbSet(T mask)
Returns most significant bit set on given mask.
Definition: RadixHeap.h:115
ogdf::RadixHeap::m_size
std::size_t m_size
Definition: RadixHeap.h:104
ogdf::RadixHeap::~RadixHeap
~RadixHeap()
Destructs the heap.
Definition: RadixHeap.h:147
ogdf::RadixHeap::size
std::size_t size() const
Number of elements contained within the heap.
Definition: RadixHeap.h:95
backward::details::move
const T & move(const T &v)
Definition: backward.hpp:243
ogdf::RadixHeap::pop
V pop()
Removes the top element from the heap and returns its value.
Definition: RadixHeap.h:168
ogdf::RadixHeapNode::next
RadixHeapNode< V, P > * next
Definition: RadixHeap.h:49
ogdf::RadixHeap::insert
void insert(RadixHeapNode< V, P > *heapNode)
Buckets with values.
Definition: RadixHeap.h:226
ogdf::RadixHeapNode::prev
RadixHeapNode< V, P > * prev
Definition: RadixHeap.h:48
ogdf::RadixHeapNode::priority
P priority
Definition: RadixHeap.h:46
ogdf::RadixHeap
Radix heap data structure implementation.
Definition: RadixHeap.h:69
ogdf::RadixHeapNode::RadixHeapNode
RadixHeapNode(const V &nodeValue, const P &nodePriority)
Definition: RadixHeap.h:51
ogdf::RadixHeap::m_buckets
std::array< Bucket, BITS+1 > m_buckets
Mask describing state of buckets (for fast lookup).
Definition: RadixHeap.h:108
ogdf::RadixHeap::RadixHeap
RadixHeap()
Creates empty heap.
Definition: RadixHeap.h:142
ogdf::RadixHeapNode::value
V value
Definition: RadixHeap.h:45
ogdf::RadixHeapNode
Definition: RadixHeap.h:43
ogdf::RadixHeap::empty
bool empty() const
Checks whether the heap is empty.
Definition: RadixHeap.h:98
ogdf::RadixHeap::push
RadixHeapNode< V, P > * push(const V &value, const P &priority)
Inserts a new node with given value and priority into a heap.
Definition: RadixHeap.h:159