00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef Heap_h
00021 #define Heap_h
00022
00023 #include "Vec.h"
00024
00025
00026
00027
00028
00029 template<class Comp>
00030 class Heap {
00031 Comp lt;
00032 vec<int> heap;
00033 vec<int> indices;
00034
00035
00036 static inline int left (int i) { return i*2+1; }
00037 static inline int right (int i) { return (i+1)*2; }
00038 static inline int parent(int i) { return (i-1) >> 1; }
00039
00040
00041 inline void percolateUp(int i)
00042 {
00043 int x = heap[i];
00044 while (i != 0 && lt(x, heap[parent(i)])){
00045 heap[i] = heap[parent(i)];
00046 indices[heap[i]] = i;
00047 i = parent(i);
00048 }
00049 heap [i] = x;
00050 indices[x] = i;
00051 }
00052
00053
00054 inline void percolateDown(int i)
00055 {
00056 int x = heap[i];
00057 while (left(i) < heap.size()){
00058 int child = right(i) < heap.size() && lt(heap[right(i)], heap[left(i)]) ? right(i) : left(i);
00059 if (!lt(heap[child], x)) break;
00060 heap[i] = heap[child];
00061 indices[heap[i]] = i;
00062 i = child;
00063 }
00064 heap [i] = x;
00065 indices[x] = i;
00066 }
00067
00068
00069 bool heapProperty (int i) const {
00070 return i >= heap.size()
00071 || ((i == 0 || !lt(heap[i], heap[parent(i)])) && heapProperty(left(i)) && heapProperty(right(i))); }
00072
00073
00074 public:
00075 Heap(const Comp& c) : lt(c) { }
00076
00077 int size () const { return heap.size(); }
00078 bool empty () const { return heap.size() == 0; }
00079 bool inHeap (int n) const { return n < indices.size() && indices[n] >= 0; }
00080 int operator[](int index) const { assert(index < heap.size()); return heap[index]; }
00081
00082 void decrease (int n) { assert(inHeap(n)); percolateUp(indices[n]); }
00083
00084
00085 void increase_ (int n) { assert(inHeap(n)); percolateDown(indices[n]); }
00086
00087
00088 void insert(int n)
00089 {
00090 indices.growTo(n+1, -1);
00091 assert(!inHeap(n));
00092
00093 indices[n] = heap.size();
00094 heap.push(n);
00095 percolateUp(indices[n]);
00096 }
00097
00098 void init_identical(int n)
00099 {
00100 indices.growTo(n+1, -1);
00101 heap.growTo(n);
00102 for(int i=0; i<n; i++)
00103 {
00104 indices[i] = i;
00105 heap[i] = i;
00106 }
00107
00108 }
00109
00110
00111 int removeMin()
00112 {
00113 int x = heap[0];
00114 heap[0] = heap.last();
00115 indices[heap[0]] = 0;
00116 indices[x] = -1;
00117 heap.pop();
00118 if (heap.size() > 1) percolateDown(0);
00119 return x;
00120 }
00121
00122
00123 void clear(bool dealloc = false)
00124 {
00125 for (int i = 0; i < heap.size(); i++)
00126 indices[heap[i]] = -1;
00127 #ifdef NDEBUG
00128 for (int i = 0; i < indices.size(); i++)
00129 assert(indices[i] == -1);
00130 #endif
00131 heap.clear(dealloc);
00132 }
00133
00134
00135
00136 void update (int n)
00137 {
00138 if (!inHeap(n))
00139 insert(n);
00140 else {
00141 percolateUp(indices[n]);
00142 percolateDown(indices[n]);
00143 }
00144 }
00145
00146
00147
00148
00149 template <class F>
00150 void filter(const F& filt) {
00151 int i,j;
00152 for (i = j = 0; i < heap.size(); i++)
00153 if (filt(heap[i])){
00154 heap[j] = heap[i];
00155 indices[heap[i]] = j++;
00156 }else
00157 indices[heap[i]] = -1;
00158
00159 heap.shrink(i - j);
00160 for (int i = heap.size() / 2 - 1; i >= 0; i--)
00161 percolateDown(i);
00162
00163 assert(heapProperty());
00164 }
00165
00166
00167
00168 bool heapProperty() const {
00169 return heapProperty(1); }
00170
00171
00172
00173 void setBounds (int n) { }
00174 void increase (int n) { decrease(n); }
00175 int getmin () { return removeMin(); }
00176
00177 };
00178
00179
00180
00181 #endif