Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
RadixHeap.h
Go to the documentation of this file.
1
32#pragma once
33
34#include <array>
35#include <cstddef>
36
37namespace ogdf {
38
39
40template<typename V, typename P>
42public:
45
48
49 RadixHeapNode(const V& nodeValue, const P& nodePriority)
50 : value(nodeValue), priority(nodePriority), prev(nullptr), next(nullptr) { }
51};
52
54
66template<typename V, typename P>
67class RadixHeap {
68public:
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
98private:
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
139template<typename V, typename P>
140RadixHeap<V, P>::RadixHeap() : m_size(0), m_minimum(0), m_bucketMask(0) {
141 m_buckets.fill(nullptr);
142}
143
144template<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
156template<typename V, typename P>
157RadixHeapNode<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
165template<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
223template<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}
Radix heap data structure implementation.
Definition RadixHeap.h:67
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
static constexpr std::size_t BITS
Definition RadixHeap.h:100
~RadixHeap()
Destructs the heap.
Definition RadixHeap.h:145
V pop()
Removes the top element from the heap and returns its value.
Definition RadixHeap.h:166
void insert(RadixHeapNode< V, P > *heapNode)
Buckets with values.
Definition RadixHeap.h:224
RadixHeap()
Creates empty heap.
Definition RadixHeap.h:140
bool empty() const
Checks whether the heap is empty.
Definition RadixHeap.h:96
std::array< Bucket, BITS+1 > m_buckets
Mask describing state of buckets (for fast lookup).
Definition RadixHeap.h:106
P m_bucketMask
Priority of the lowest element so far.
Definition RadixHeap.h:105
std::size_t m_size
Definition RadixHeap.h:102
P m_minimum
Number of elements.
Definition RadixHeap.h:104
std::size_t size() const
Number of elements contained within the heap.
Definition RadixHeap.h:93
static std::size_t msbSet(T mask)
Returns most significant bit set on given mask.
Definition RadixHeap.h:113
RadixHeapNode< V, P > * next
Definition RadixHeap.h:47
RadixHeapNode(const V &nodeValue, const P &nodePriority)
Definition RadixHeap.h:49
RadixHeapNode< V, P > * prev
Definition RadixHeap.h:46
The namespace for all OGDF objects.