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