00001
00002
00003
00004
00005
00006
00007
00008
00043 #ifdef _MSC_VER
00044 #pragma once
00045 #endif
00046
00047 #ifndef OREAS_BINARY_HEAP2_H
00048 #define OREAS_BINARY_HEAP2_H
00049
00050 #include <ogdf/basic/HeapBase.h>
00051
00052 namespace ogdf {
00053
00098
00099
00100
00101
00102
00103 template <class key, class HeapObject>
00104 class BinaryHeap2 : public HeapBase<key, HeapObject>
00105 {
00106 public:
00108 BinaryHeap2(int startSize = 128);
00109
00110
00111
00112
00113
00114 virtual ~BinaryHeap2() {
00115 if (m_heapArray) delete[] m_heapArray;
00116 }
00117
00118
00120 const BinaryHeap2& operator=(const BinaryHeap2<key, HeapObject>& rhs);
00121
00122
00123
00124
00126 void insert(HeapObject& obj, key& p, int* keyUpdate = 0);
00127
00129 virtual void makeHeap();
00130
00131
00132
00133
00134
00136
00137 HeapObject extractMin();
00138
00140
00141 virtual void decreaseKey(int index, key priority);
00142
00143
00144
00145
00146
00148 HeapObject minRet() const {return m_heapArray[1].m_object;}
00149
00150 key getPriority(int index) const
00151 {
00152 OGDF_ASSERT( (index > 0) && (index <= HeapBase<key,HeapObject>::m_size) );
00153 return m_heapArray[index].m_priority;
00154 }
00155
00157 int capacity() const { return m_arraySize; }
00158
00160 int size() const { return HeapBase<key,HeapObject>::m_size; }
00161
00163 int empty() const { return HeapBase<key,HeapObject>::empty(); }
00164
00166
00170 void clear();
00171
00172 protected:
00174 void siftUp(int pos);
00175
00177 void siftDown(int pos);
00178
00179
00180
00181
00183 int parentIndex(int num)
00184 {
00185 OGDF_ASSERT(num>0);
00186 return num/2;
00187 }
00188
00190 int leftChildIndex(int num)
00191 {
00192 OGDF_ASSERT(num>0);
00193 return 2*num;
00194 }
00195
00197 int rightChildIndex(int num)
00198 {
00199 OGDF_ASSERT(num>0);
00200 return 2*num+1;
00201 }
00202
00204 bool hasLeft(int num)
00205 {
00206 OGDF_ASSERT(num>0);
00207 return (leftChildIndex(num) <= HeapBase<key,HeapObject>::m_size);
00208 }
00209
00211 bool hasRight(int num)
00212 {
00213 OGDF_ASSERT(num>0);
00214 return (rightChildIndex(num) <= HeapBase<key,HeapObject>::m_size);
00215 }
00216
00217
00218
00219 int arrayBound(int arraySize) {return arraySize+1;}
00220 int higherArrayBound(int arraySize) {return 2*arraySize+1;}
00221 int higherArraySize(int arraySize) {return 2*arraySize;}
00222 int lowerArrayBound(int arraySize) {return arraySize/2+1;}
00223 int lowerArraySize(int arraySize) {return arraySize/2;}
00224
00225 void init(int initSize);
00226
00227 private:
00228
00229 struct HeapEntry
00230 {
00231 key m_priority;
00232 HeapObject m_object;
00233
00234
00235 int m_pos;
00236 int* m_foreignPos;
00237
00239 HeapEntry() {m_priority = 0;
00240 m_pos = 0;
00241 m_foreignPos = 0;
00242 }
00243
00245
00249 HeapEntry(key k, const HeapObject& ob) {m_priority = k; m_object = ob;
00250 m_foreignPos = 0;
00251
00252 }
00253
00255
00261 HeapEntry(key k, const HeapObject& ob, int pos, int* fp)
00262 {
00263 m_priority = k;
00264 m_object = ob;
00265 if (fp == 0) m_foreignPos = 0;
00266 else m_foreignPos = fp;
00267 m_pos = pos;
00268 }
00269 };
00270
00271 HeapEntry* m_heapArray;
00272
00273
00274
00275
00276 int m_arraySize;
00277
00278 int m_startSize;
00279
00280 };
00281
00282
00283
00284 }
00285
00286
00287
00288
00289
00290 #include <ogdf/basic/basic.h>
00291
00292 namespace ogdf {
00293
00294
00295
00296 template <class key, class HeapObject>
00297 BinaryHeap2<key, HeapObject>::BinaryHeap2(int startSize)
00298 : HeapBase<key, HeapObject>()
00299 {
00300 init(startSize);
00301 }
00302
00303 template <class key, class HeapObject>
00304 void BinaryHeap2<key, HeapObject>::init(int initSize)
00305 {
00306
00307 m_arraySize = initSize;
00308 m_heapArray = new HeapEntry[arrayBound(m_arraySize)];
00309
00310 m_startSize = initSize;
00311
00312 HeapBase<key,HeapObject>::m_size = 0;
00313 }
00314
00315 template <class key, class HeapObject>
00316 void BinaryHeap2<key, HeapObject>::clear()
00317 {
00318 if (m_heapArray) delete[] m_heapArray;
00319 init(m_startSize);
00320 }
00321
00322
00323
00324
00325
00326
00327 template <class key, class HeapObject>
00328 void BinaryHeap2<key, HeapObject>::siftUp(int pos)
00329 {
00330 OGDF_ASSERT( (pos > 0) && (pos <= HeapBase<key,HeapObject>::m_size) )
00331
00332 if (pos == 1)
00333 {
00334 m_heapArray[1].m_pos = 1;
00335 if (m_heapArray[1].m_foreignPos != 0)
00336 *(m_heapArray[1].m_foreignPos) = 1;
00337 return;
00338 }
00339
00340 HeapEntry tempEntry = m_heapArray[pos];
00341 int run = pos;
00342 while ( (parentIndex(run) >= 1) &&
00343 (m_heapArray[parentIndex(run)].m_priority > tempEntry.m_priority) )
00344 {
00345 m_heapArray[run] = m_heapArray[parentIndex(run)];
00346 if (m_heapArray[run].m_foreignPos != 0) *(m_heapArray[run].m_foreignPos) = run;
00347 run = parentIndex(run);
00348 }
00349
00350 m_heapArray[run] = tempEntry;
00351 m_heapArray[run].m_pos = run;
00352 if (m_heapArray[run].m_foreignPos != 0) *(m_heapArray[run].m_foreignPos) = run;
00353
00354
00355 }
00356
00357
00358
00359 template <class key, class HeapObject>
00360 void BinaryHeap2<key, HeapObject>::siftDown(int pos)
00361 {
00362 OGDF_ASSERT( (pos > 0) && (pos <= HeapBase<key,HeapObject>::m_size) );
00363
00364 if (pos >= int(HeapBase<key,HeapObject>::m_size/2)+1)
00365 {
00366 m_heapArray[pos].m_pos = pos;
00367 if (m_heapArray[pos].m_foreignPos != 0) *(m_heapArray[pos].m_foreignPos) = pos;
00368 return;
00369 }
00370
00371 key sPrio = getPriority(pos);
00372 int sIndex = pos;
00373
00374 if (hasLeft(pos) && (getPriority(leftChildIndex(pos)) < sPrio) )
00375 {
00376 sIndex = leftChildIndex(pos);
00377 sPrio = getPriority(leftChildIndex(pos));
00378 }
00379 if (hasRight(pos) && (getPriority(rightChildIndex(pos)) < sPrio) )
00380 {
00381 sIndex = rightChildIndex(pos);
00382 sPrio = getPriority(rightChildIndex(pos));
00383 }
00384
00385 if (sIndex != pos)
00386 {
00387 HeapEntry tempEntry = m_heapArray[pos];
00388 m_heapArray[pos] = m_heapArray[sIndex];
00389 m_heapArray[sIndex] = tempEntry;
00390
00391
00392 m_heapArray[pos].m_pos = pos;
00393 if (m_heapArray[pos].m_foreignPos != 0) *(m_heapArray[pos].m_foreignPos) = pos;
00394 m_heapArray[sIndex].m_pos = sIndex;
00395 if (m_heapArray[sIndex].m_foreignPos != 0) *(m_heapArray[sIndex].m_foreignPos) = sIndex;
00396
00397 siftDown(sIndex);
00398 }
00399 else
00400 {
00401 m_heapArray[pos].m_pos = pos;
00402 if (m_heapArray[pos].m_foreignPos != 0) *(m_heapArray[pos].m_foreignPos) = pos;
00403 }
00404
00405
00406 }
00407
00408
00409 template <class key, class HeapObject>
00410 void BinaryHeap2<key, HeapObject>::makeHeap()
00411 {
00412
00413
00414 for (int i=HeapBase<key,HeapObject>::m_size/2; i > 0; i--)
00415 siftDown(i);
00416 }
00417
00418 template <class key, class HeapObject>
00419 void BinaryHeap2<key, HeapObject>::decreaseKey(int index, key priority)
00420 {
00421 HeapEntry& he = m_heapArray[index];
00422
00423
00424 if (he.m_priority < priority) OGDF_THROW_PARAM(AlgorithmFailureException, afcIllegalParameter);
00425
00426 he.m_priority = priority;
00427 siftUp(index);
00428
00429 }
00430
00431
00432 template <class key, class HeapObject>
00433 HeapObject BinaryHeap2<key, HeapObject>::extractMin()
00434 {
00435 OGDF_ASSERT((!HeapBase<key,HeapObject>::empty()));
00436
00437 HeapEntry tempEntry = m_heapArray[1];
00438
00439 HeapBase<key,HeapObject>::m_size--;
00440
00441 if (HeapBase<key,HeapObject>::m_size > 0)
00442 {
00443 m_heapArray[1] = m_heapArray[HeapBase<key,HeapObject>::m_size+1];
00444
00445
00446 if ((HeapBase<key,HeapObject>::m_size < (m_arraySize/3)) && (m_arraySize > 2*m_startSize-1))
00447 {
00448 HeapEntry* tempHeap = new HeapEntry[lowerArrayBound(m_arraySize)];
00449 for (int i = 1; i <= HeapBase<key,HeapObject>::m_size ; i++)
00450 tempHeap[i] = m_heapArray[i];
00451 delete[] m_heapArray;
00452 m_heapArray = tempHeap;
00453 m_arraySize = lowerArraySize(m_arraySize);
00454
00455 }
00456
00457
00458 siftDown(1);
00459 }
00460
00461 return tempEntry.m_object;
00462
00463 }
00464
00465
00466
00467
00468 template <class key, class HeapObject>
00469 void BinaryHeap2<key, HeapObject>::insert(HeapObject& ho, key& priority, int* keyUpdate)
00470 {
00471 OGDF_ASSERT((HeapBase<key,HeapObject>::m_size) < m_arraySize);
00472 HeapBase<key,HeapObject>::m_size++;
00473
00474 if (HeapBase<key,HeapObject>::m_size == m_arraySize)
00475 {
00476 HeapEntry* tempHeap = new HeapEntry[higherArrayBound(m_arraySize)];
00477 for (int i = 1; i <= m_arraySize ; i++)
00478 tempHeap[i] = m_heapArray[i];
00479 delete[] m_heapArray;
00480 m_heapArray = tempHeap;
00481 m_arraySize = higherArraySize(m_arraySize);
00482
00483 }
00484
00485
00486 m_heapArray[HeapBase<key,HeapObject>::m_size] = HeapEntry(priority, ho, HeapBase<key,HeapObject>::m_size, keyUpdate);
00487
00488 siftUp(HeapBase<key,HeapObject>::m_size);
00489
00490 }
00491
00492
00493
00494 template <class key, class HeapObject>
00495 const BinaryHeap2<key, HeapObject>& BinaryHeap2<key, HeapObject>::operator=(const BinaryHeap2<key, HeapObject>& rhs)
00496 {
00497 if (this != &rhs)
00498 {
00499 if (m_heapArray && !(m_arraySize == rhs.m_arraySize))
00500 {
00501 delete[] m_heapArray;
00502 m_heapArray = 0;
00503 }
00504
00505 if (!m_heapArray)
00506 m_heapArray = new HeapEntry[arrayBound(rhs.m_arraySize)];
00507
00508 OGDF_ASSERT(m_heapArray);
00509
00510 HeapBase<key,HeapObject>::m_size = rhs.m_size;
00511
00512 m_startSize = rhs.m_startSize;
00513
00514 m_arraySize = rhs.m_arraySize;
00515
00516 for (int i = 1; i <= HeapBase<key,HeapObject>::m_size ; i++)
00517 m_heapArray[i] = rhs.m_heapArray[i];
00518
00519 }
00520 return *this;
00521 }
00522
00523
00524
00525 }
00526
00527 #endif