Loading [MathJax]/extensions/tex2jax.js

Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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