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