00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef OAKBINARYMINHEAP_H
00025 #define OAKBINARYMINHEAP_H
00026
00027 #define HEAP_INITIAL_SIZE 4
00028
00029 #include <map>
00030 #include <iostream>
00031 #include <pasync.h>
00032
00033 USING_PTYPES
00034
00035
00036
00037
00038
00039
00040
00041 template<class E, class Comparer>
00042 class OakBinaryMinHeap : semaphore, mutex
00043 {
00044 private:
00045 E ** elements;
00046 std::map<E*, int> positions;
00047
00048 Comparer comp;
00049 int heap_size;
00050 int last;
00051 inline int parent(int i) { return i/2; }
00052 inline int left(int i) { return i*2; }
00053 inline int right(int i) { return i*2+1; }
00054
00055 inline void moveup(int i)
00056 {
00057
00058 swap(i,parent(i));
00059 heapify(parent(i));
00060 }
00061
00062 inline void swap(int i, int j)
00063 {
00064
00065 E * tmp = elements[i];
00066 elements[i] = elements[j];
00067 elements[j] = tmp;
00068 positions[elements[i]] = i;
00069 positions[elements[j]] = j;
00070 }
00071
00072 void heapify(int i)
00073 {
00074
00075 if(i > 0)
00076 {
00077 if(comp(*elements[i],*elements[parent(i)]))
00078 {
00079 moveup(i);
00080 return;
00081 }
00082 }
00083 if(i != last)
00084 {
00085
00086 int l = left(i);
00087 int r = right(i);
00088 int smallest = i;
00089 if(l <= last && comp(*elements[l],*elements[i]))
00090 {
00091 smallest = l;
00092 }
00093 if(r <= last && comp(*elements[r],*elements[smallest]))
00094 {
00095 smallest = r;
00096 }
00097 if(smallest != i)
00098 {
00099 swap(i,smallest);
00100 heapify(smallest);
00101 }
00102 }
00103 }
00104
00105
00106
00107 void checkHeapSize()
00108 {
00109 if(last+1 == heap_size)
00110 {
00111 std::cout << "Expand heap from: " << heap_size << " to " << (heap_size * 2) << std::endl;
00112 E **tmp = new E*[heap_size * 2];
00113 memcpy(tmp, elements, heap_size * sizeof(E*));
00114 delete[] elements;
00115 elements = tmp;
00116 heap_size = heap_size * 2;
00117 }
00118 }
00119
00120 public:
00121 OakBinaryMinHeap() : semaphore(0)
00122 {
00123 positions.clear();
00124 heap_size = HEAP_INITIAL_SIZE;
00125
00126 elements = 0;
00127 elements = new E*[heap_size];
00128 this->last = -1;
00129 }
00130 ~OakBinaryMinHeap()
00131 {
00132 delete[] elements;
00133 }
00134 void clear()
00135 {
00136 this->last = -1;
00137 }
00138
00139 void insert(E * e)
00140 {
00141 enter();
00142 checkHeapSize();
00143 elements[++last] = e;
00144 positions.insert(std::make_pair(e,last));
00145 heapify(last);
00146 leave();
00147 post();
00148 }
00149 E * getMin()
00150 {
00151 wait();
00152 enter();
00153 E * tmpE = elements[0];
00154 elements[0] = elements[last];
00155 positions.erase(tmpE);
00156 positions[elements[0]] = 0;
00157 last--;
00158 heapify(0);
00159 leave();
00160 return tmpE;
00161 }
00162
00163 E * peek()
00164 {
00165 E * tmpE;
00166 wait();
00167 enter();
00168 tmpE = elements[0];
00169 leave();
00170 post();
00171 return tmpE;
00172 }
00173
00174 inline int size() const { return last + 1; };
00175
00176 void heapify(E * e)
00177 {
00178 enter();
00179 heapify(positions[e]);
00180 leave();
00181 }
00182 };
00183
00184 #endif
00185