Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
bheap.inc
Go to the documentation of this file.
1
29#pragma once
30
31namespace abacus {
32
33
34template<class Type, class Key>
36 :
37 heap_(size),
38 keys_(size),
39 n_(0)
40{ }
41
42
43template<class Type, class Key>
44AbaBHeap<Type, Key>::AbaBHeap(
45 const ArrayBuffer<Type> &elems,
47 :
48 heap_(elems),
49 keys_(keys),
50 n_(keys.size())
51{
52 for (int i = father(n_-1); i>=0; --i)
53 heapify(i);
54}
55
56
57template<class Type, class Key>
58std::ostream& operator<<(std::ostream& out, const AbaBHeap<Type, Key>& rhs)
59{
60 for(int i = 0; i < rhs.n_; i ++)
61 out << rhs.heap_[i] << " (" << rhs.keys_[i] << ") ";
62 out << std::endl;
63 return out;
64}
65
66
67template<class Type, class Key>
68void AbaBHeap<Type, Key>::insert(Type elem, Key key)
69{
71 OGDF_ASSERT(n_ < size());
72
73 // go up towards the root and insert \a elem
74 /* The position \a n_ of the array representing the heap becomes the
75 * new leaf of corresponding binary tree. However, inserting the new
76 * element at this position could destroy the heap property.
77 * Therefore, we go up to the root until we find the position
78 * for inserting the new element. While going up to this position
79 * we move earlier inserted elements already to their new position.
80 */
81 int i = n_;
82 int f = father(i);
83
84 while (i > 0 && keys_[f] > key) {
85 heap_[i] = heap_[f];
86 keys_[i] = keys_[f];
87 i = f;
88 f = father(i);
89 }
90 heap_[i] = elem;
91 keys_[i] = key;
92 ++n_;
93}
94
95
96template<class Type, class Key>
97Type AbaBHeap<Type, Key>::getMin() const
98{
99 // is the heap empty?
100 /* The check on an empty heap is only performed if is the code
101 * is compiled with the precompiler flag <tt>OGDF_DEBUG</tt>.
102 */
103 OGDF_ASSERT(!empty());
104
105 return heap_[0];
106}
107
108
109template<class Type, class Key>
110Key AbaBHeap<Type, Key>::getMinKey() const
111{
112 // is the heap empty?
113 /* The check on an empty heap is only performed if is the code
114 * is compiled with the precompiler flag <tt>OGDF_DEBUG</tt>.
115 */
116 OGDF_ASSERT(!empty());
117
118 return keys_[0];
119}
120
121
122template<class Type, class Key>
123Type AbaBHeap<Type, Key>::extractMin()
124{
125 Type min = getMin();
126
127 --n_;
128
129 if (n_ != 0) {
130 heap_[0] = heap_[n_];
131 keys_[0] = keys_[n_];
132 heapify(0);
133 }
134
135 return min;
136}
137
138
139template<class Type, class Key>
140void AbaBHeap<Type, Key>::clear()
141{
142 n_ = 0;
143}
144
145
146template<class Type, class Key>
147inline int AbaBHeap<Type, Key>::size() const
148{
149 return heap_.size();
150}
151
152
153template <class Type, class Key>
154inline int AbaBHeap<Type, Key>::number() const
155{
156 return n_;
157}
158
159
160template<class Type, class Key>
161inline bool AbaBHeap<Type, Key>::empty() const
162{
163 if(n_ == 0) return true;
164 return false;
165}
166
167
168template<class Type, class Key>
169void AbaBHeap<Type, Key>::realloc(int newSize)
170{
171 heap_.realloc(newSize);
172 keys_.realloc(newSize);
173}
174
175
176template<class Type, class Key>
177void AbaBHeap<Type, Key>::check() const
178{
179 for(int i = 0; i < n_/2; i++)
180 if (keys_[i] > keys_[leftSon(i)] || (rightSon(i) < n_ && heap_[i] > heap_[rightSon(i)])) {
181 Logger::ifout() << "AbaBHeap:check(): " << i << " violates heap\n";
182 OGDF_THROW_PARAM(AlgorithmFailureException, ogdf::AlgorithmFailureCode::BHeap);
183 }
184}
185
186
187template <class Type, class Key>
188inline int AbaBHeap<Type, Key>::leftSon(int i) const
189{
190 return 2*i + 1;
191}
192
193
194template <class Type, class Key>
195int AbaBHeap<Type, Key>::rightSon(int i) const
196{
197 return 2*i + 2;
198}
199
200
201template <class Type, class Key>
202inline int AbaBHeap<Type, Key>::father(int i) const
203{
204 return (i-1)/2;
205}
206
207
208template <class Type, class Key>
209void AbaBHeap<Type, Key>::heapify(int i)
210{
212 int smallest; // smallest heap element of i,l, and r
213 Type tmp; // temporary object for swapping elements of the heap
214 Key ktmp; // temporary object for swapping the keys
215
216 // restore the heap property
217 /* Node \a i violates the heap property if it has a son with
218 * a smaller key. If we swap the element and the key of node \a i
219 * with the element and the key of the smaller one of its two sons,
220 * then the heap property is restored for node \a i. However, it
221 * might be now destroyed for node \a smallest. So we
222 * iterate this process until no swap is performed.
223 */
224 while (i < n_) {
226 int l = leftSon(i);
227 int r = rightSon(i);
228 if (l < n_ && keys_[i] > keys_[l]) smallest = l;
229 else smallest = i;
230 if (r < n_ && keys_[smallest] > keys_[r]) smallest = r;
231
232 if (smallest != i) {
234 tmp = heap_[i];
235 heap_[i] = heap_[smallest];
236 heap_[smallest] = tmp;
237
238 ktmp = keys_[i];
239 keys_[i] = keys_[smallest];
240 keys_[smallest] = ktmp;
241
242 i = smallest;
243 }
244 else break;
245 }
246}
247
248}
AbaBHeap(int size)
A constructor.
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:41
#define OGDF_THROW_PARAM(CLASS, PARAM)
Replacement for throw.
Definition exceptions.h:54
int r[]
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
std::ostream & operator<<(std::ostream &os, const ogdf::Array< E, INDEX > &a)
Prints array a to output stream os.
Definition Array.h:978