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