File indexing completed on 2025-08-03 08:19:36
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef GTL_BIN_HEAP_H
0010 #define GTL_BIN_HEAP_H
0011
0012 #include <GTL/GTL.h>
0013
0014 #include <cassert>
0015 #include <vector>
0016 #include <map>
0017
0018 __GTL_BEGIN_NAMESPACE
0019
0020
0021
0022
0023
0024 template <class T>
0025 class heap_node
0026 {
0027 public:
0028
0029
0030
0031
0032 heap_node()
0033 {
0034 }
0035
0036
0037
0038
0039 heap_node(const T& n) : data(n)
0040 {
0041 }
0042
0043
0044
0045
0046
0047 T data;
0048
0049
0050
0051
0052
0053 int pos;
0054 };
0055
0056
0057
0058
0059
0060
0061
0062 template <class T, class Pred>
0063 class bin_heap
0064 {
0065 public:
0066
0067
0068
0069
0070
0071 bin_heap(const Pred& prd);
0072
0073
0074
0075
0076
0077
0078
0079 bin_heap(const Pred& prd, const int est_size);
0080
0081
0082
0083
0084
0085
0086 bin_heap(const bin_heap<T, Pred>& bh);
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098 bin_heap<T, Pred>& operator=(const bin_heap<T, Pred>& bh);
0099
0100
0101
0102
0103 ~bin_heap();
0104
0105
0106
0107
0108
0109
0110 void push(const T& ins);
0111
0112
0113
0114
0115 void pop();
0116
0117
0118
0119
0120
0121
0122 const T& top() const;
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136 void changeKey(const T& cha);
0137
0138
0139
0140
0141
0142
0143 bool is_empty() const;
0144
0145
0146
0147
0148
0149 void clear();
0150 private:
0151
0152
0153
0154
0155 const Pred& prd;
0156
0157
0158
0159
0160
0161 int size;
0162
0163
0164
0165
0166
0167
0168 int capacity;
0169
0170
0171
0172
0173
0174 vector<heap_node<T>* > container;
0175
0176
0177
0178
0179
0180 map<T, heap_node<T>* > heap_node_map;
0181
0182
0183
0184
0185
0186 void bubble_up(heap_node<T>* const n);
0187
0188
0189
0190
0191
0192 void bubble_down(heap_node<T>* const n);
0193 #ifdef _DEBUG
0194 public:
0195
0196
0197
0198
0199 void print_data_container();
0200 #endif
0201 };
0202
0203
0204
0205 template <class T, class Pred>
0206 bin_heap<T, Pred>::bin_heap(const Pred& prd) :
0207 prd(prd), size(0), capacity(50)
0208 {
0209 container.resize(capacity);
0210 }
0211
0212
0213 template <class T, class Pred>
0214 bin_heap<T, Pred>::bin_heap(const Pred& prd, const int est_size) :
0215 prd(prd), size(0), capacity(50)
0216 {
0217 if (est_size > 50)
0218 {
0219 capacity = est_size;
0220 }
0221 container.resize(capacity);
0222 }
0223
0224
0225 template <class T, class Pred>
0226 bin_heap<T, Pred>::bin_heap(const bin_heap<T, Pred>& bh) :
0227 prd(bh.prd), size(bh.size), capacity(bh.capacity)
0228 {
0229 container.resize(capacity);
0230 for (int i = 0; i < size; ++i)
0231 {
0232 container[i] = new heap_node<T>(bh.container[i]->data);
0233 }
0234 }
0235
0236
0237 template <class T, class Pred>
0238 bin_heap<T, Pred>& bin_heap<T, Pred>::operator=(const bin_heap<T, Pred>& bh)
0239 {
0240 if (this != &bh)
0241 {
0242 assert(&prd == &(bh.prd));
0243 clear();
0244 size = bh.size;
0245 capacity = bh.capacity;
0246 container.resize(capacity);
0247 for (int i = 0; i < size; ++i)
0248 {
0249 container[i] = new heap_node<T>(bh.container[i]->data);
0250 }
0251 }
0252 return *this;
0253 }
0254
0255
0256 template <class T, class Pred>
0257 bin_heap<T, Pred>::~bin_heap()
0258 {
0259 clear();
0260 }
0261
0262
0263 template <class T, class Pred>
0264 void bin_heap<T, Pred>::push(const T& ins)
0265 {
0266 if (size == capacity)
0267 {
0268
0269 capacity *= 2;
0270 container.resize(capacity);
0271 }
0272 heap_node<T>* n = new heap_node<T>(ins);
0273 n->pos = size;
0274 container[size] = n;
0275 heap_node_map[ins] = n;
0276 ++size;
0277 bubble_up(n);
0278 }
0279
0280
0281 template <class T, class Pred>
0282 void bin_heap<T, Pred>::pop()
0283 {
0284 assert(size > 0);
0285
0286 heap_node_map.erase(container[0]->data);
0287 delete container[0];
0288
0289 if (size > 1)
0290 {
0291 container[0] = container[--size];
0292 container[0]->pos = 0;
0293
0294 bubble_down(container[0]);
0295 }
0296 else
0297 {
0298 size = 0;
0299 }
0300 }
0301
0302
0303 template <class T, class Pred>
0304 const T& bin_heap<T, Pred>::top() const
0305 {
0306 return container[0]->data;
0307 }
0308
0309
0310 template <class T, class Pred>
0311 void bin_heap<T, Pred>::changeKey(const T& cha)
0312 {
0313 int pos = heap_node_map[cha]->pos;
0314 heap_node<T>* n = container[pos];
0315 if (pos != 0)
0316 {
0317 heap_node<T>* father = container[(pos - 1) / 2];
0318 if (prd(n->data, father->data))
0319 {
0320 bubble_up(n);
0321 return;
0322 }
0323 }
0324 bubble_down(n);
0325 }
0326
0327
0328 template <class T, class Pred>
0329 bool bin_heap<T, Pred>::is_empty() const
0330 {
0331
0332 return size == 0;
0333 }
0334
0335
0336 template <class T, class Pred>
0337 void bin_heap<T, Pred>::clear()
0338 {
0339 for (int i = 0; i < size; ++i)
0340 {
0341 delete container[i];
0342 }
0343 size = 0;
0344 heap_node_map.clear();
0345 }
0346
0347
0348 template <class T, class Pred>
0349 void bin_heap<T, Pred>::bubble_up(heap_node<T>* const n)
0350 {
0351 int pos = n->pos;
0352
0353 while ((pos != 0) &&
0354 (prd(n->data, container[(pos - 1) / 2]->data)))
0355 {
0356
0357 container[pos] = container[(pos - 1) / 2];
0358 container[pos]->pos = pos;
0359
0360 pos = (pos - 1) / 2;
0361 }
0362
0363 container[pos] = n;
0364 container[pos]->pos = pos;
0365 }
0366
0367
0368 template <class T, class Pred>
0369 void bin_heap<T, Pred>::bubble_down(heap_node<T>* const n)
0370 {
0371 int pos = n->pos;
0372 int j = 0;
0373 while (pos < size / 2)
0374 {
0375 j = 2 * pos + 1;
0376
0377 if ((j < size - 1) &&
0378 (prd(container[j + 1]->data, container[j]->data)))
0379 {
0380 ++j;
0381 }
0382
0383 if (!prd(container[j]->data, n->data))
0384 {
0385 break;
0386 }
0387
0388 container[pos] = container[j];
0389 container[pos]->pos = pos;
0390
0391 pos = j;
0392 }
0393
0394 container[pos] = n;
0395 container[pos]->pos = pos;
0396 }
0397
0398 #ifdef _DEBUG
0399 template <class T, class Pred>
0400 void bin_heap<T, Pred>::print_data_container()
0401 {
0402 if (size == 0)
0403 {
0404 cout << "empty";
0405 }
0406 else
0407 {
0408 for (int pos = 0; pos < size; ++pos)
0409 {
0410 cout << container[pos]->data << " ";
0411 }
0412 }
0413 cout << endl;
0414 }
0415 #endif
0416
0417
0418
0419 __GTL_END_NAMESPACE
0420
0421 #endif
0422
0423
0424
0425