00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00024 #ifndef __AbstractHeap_h
00025 #define __AbstractHeap_h
00026
00027 #ifdef __GNUC__
00028 #pragma interface
00029 #endif
00030
00031 #ifdef NON_ANSI
00032 #include <iostream.h>
00033 #else
00034 #include <iostream>
00035 using namespace std;
00036 #endif
00037
00038 #include "_generic.h"
00039 #include "errmsg.h"
00040
00041
00042
00043 template <class T, class KEY>
00044 class AbstractHeap
00045 {
00046 public:
00047
00049 explicit AbstractHeap(const char* nameBuff = "Unnamed",
00050 int initSize = defaultSize,
00051 int quantumChoice = defaultQuantum);
00053 virtual ~AbstractHeap();
00054
00056 bool empty() const {return (used == 0);}
00058 operator bool() const {return (used != 0);}
00060 int size() const { return used; }
00061
00063 OrderSense sense() {return Sense;}
00065 void setSense(OrderSense sense_) {Sense=sense_;}
00066
00068 T* top() const
00069 {
00070 if (used <= 0)
00071 cerr << "Empty heap: " << name << endl;
00072 return tree[1];
00073 }
00075 T* member(int element) const
00076 { return tree[element]; }
00081 T* find(KEY& key);
00082
00084 virtual void add(KEY& key)
00085 {insert(&key);}
00090 virtual void add(KEY& key, T*& item)
00091 {item = insert(&key);}
00097 virtual void remove(KEY& key, bool& status)
00098 {
00099 T* tmp = find(key);
00100 if (tmp) extract(tmp,status);
00101 else status = false;
00102 }
00108 virtual void remove(T*& item, bool& status)
00109 {
00110 if (!item)
00111 status = false;
00112 else {
00113 extract(item,status);
00114 item = 0;
00115 }
00116 }
00122 virtual void remove(T*& item, KEY& key, bool& status)
00123 {
00124 if (!item)
00125 status = false;
00126 else {
00127 key = item->key();
00128 extract(item,status);
00129 item = 0;
00130 }
00131 }
00132
00134 int write(ostream& os) const;
00136 int read(istream& is);
00137
00139 int prune();
00140
00142 static const int defaultSize;
00144 static const int defaultQuantum;
00146 void clear();
00147
00148 protected:
00149
00151 OrderSense Sense;
00152
00154 virtual T* insert(KEY* item);
00160 virtual void extract(T* item, bool& status);
00162 int refloatElement(int element);
00163
00165 virtual int prunable(T* ) {return 0;}
00166
00168 virtual void moveEffect(T* ) {}
00170 virtual void addEffect(T* ) {}
00172 virtual void removeEffect(T* item)
00173 {item->element=0;}
00175 virtual void pruneEffect(T* ) {}
00176
00178 int used;
00180 int allocated;
00182 int quantum;
00184 T** tree;
00186 const char* name;
00187
00189 void swap(int a,int b);
00191 int floatUp(int element);
00193 int sinkDown(int element);
00194
00195 };
00196
00197
00198 template <class T, class KEY>
00199 const int AbstractHeap<T,KEY>::defaultSize = 256;
00200 template <class T, class KEY>
00201 const int AbstractHeap<T,KEY>::defaultQuantum = 256;
00202
00203 template <class T, class KEY>
00204 inline ostream& operator<<(ostream& output, const AbstractHeap<T,KEY>& heap)
00205 { heap.write(output); return(output); }
00206
00207
00208
00209 template <class T, class KEY>
00210 inline istream& operator>>(istream& input, AbstractHeap<T,KEY>& heap)
00211 { heap.read(input); return(input); }
00212
00213
00214
00215 template <class T, class KEY>
00216 AbstractHeap<T,KEY>::AbstractHeap(const char* nameBuff,
00217 int initSize,
00218 int quantumChoice) :
00219 Sense(increasing),
00220 used(0),
00221 allocated(initSize),
00222 quantum(quantumChoice),
00223 name(nameBuff)
00224 {
00225 if (!name)
00226 name = "";
00227 tree = (new (T*[initSize])) - 1;
00228 }
00229
00230
00231 template <class T, class KEY>
00232 AbstractHeap<T,KEY>::~AbstractHeap()
00233 {
00234 delete[] (tree + 1);
00235 }
00236
00237
00238
00239 template <class T, class KEY>
00240 void AbstractHeap<T,KEY>::swap(int a,int b)
00241 {
00242 register T* t1 = tree[a];
00243 register T* t2 = tree[b];
00244 tree[a] = t2;
00245 tree[b] = t1;
00246 t1->element=b;
00247 t2->element=a;
00248 moveEffect(t1);
00249 moveEffect(t2);
00250 }
00251
00252
00253
00254 template <class T, class KEY>
00255 int AbstractHeap<T,KEY>::floatUp(int element)
00256 {
00257 int next;
00258 while (((next = element >> 1) >= 1) &&
00259 ((Sense* tree[element]->compare(tree[next]->key())) < 0))
00260 {
00261 swap(element,next);
00262 element = next;
00263 }
00264 return element;
00265 }
00266
00267
00268 template <class T, class KEY>
00269 int AbstractHeap<T,KEY>::sinkDown(int element)
00270 {
00271 int child;
00272 while ((child = element << 1) <= used)
00273 {
00274 if ((child < used) && ((Sense*tree[child+1]->compare(tree[child]->key()))<0))
00275 child++;
00276 if ((Sense*tree[element]->compare(tree[child]->key()))<0)
00277 return(element);
00278 swap(element,child);
00279 element = child;
00280 }
00281 return element;
00282 }
00283
00284
00285 template <class T, class KEY>
00286 int AbstractHeap<T,KEY>::refloatElement(int element)
00287 {
00288 int newLocation = floatUp(element);
00289 if (newLocation == element)
00290 return sinkDown(element);
00291 else
00292 return element;
00293 }
00294
00295
00296 template <class T, class KEY>
00297 T* AbstractHeap<T,KEY>::insert(KEY* newkey)
00298 {
00299 if (used == allocated) {
00300 if (quantum > 0) {
00301 allocated += quantum;
00302 T** oldTree = tree;
00303 tree = (new (T*[allocated])) - 1;
00304 for (int i=1; i<=used; i++)
00305 tree[i] = oldTree[i];
00306 delete [] (oldTree + 1);
00307 }
00308 else
00309 cerr << name << "heap overflowed at " << (used+1) << " elements" << endl;
00310 }
00311
00312 T* item = new T(newkey);
00313 tree[++used] = item;
00314 addEffect(item);
00315 item->element=used;
00316 moveEffect(item);
00317 floatUp(used);
00318 return item;
00319 }
00320
00321
00322 template <class T, class KEY>
00323 void AbstractHeap<T,KEY>::extract(T* item, bool& status)
00324 {
00325 int element = item->element;
00326 if ((element < 1) || (element > used)) {
00327 status=false;
00328 return;
00329 }
00330
00331 removeEffect(item);
00332 delete item;
00333 if (element < used) {
00334 T* t = tree[used];
00335 tree[element] = t;
00336 used--;
00337 t->element=element;
00338 moveEffect(t);
00339 refloatElement(element);
00340 }
00341 else
00342 used--;
00343
00344 status=true;
00345 }
00346
00347
00348 template <class T, class KEY>
00349 int AbstractHeap<T,KEY>::prune()
00350 {
00351 int n = used;
00352 while (n > (used >> 1)) {
00353 if (prunable(tree[n])) {
00354 T* item = tree[n];
00355 pruneEffect(item);
00356 deleteElement(n);
00357 if (n > used)
00358 n = used;
00359 }
00360 else
00361 n--;
00362 }
00363 return used;
00364 }
00365
00366
00367 template <class T, class KEY>
00368 int AbstractHeap<T,KEY>::write(ostream& os) const
00369 {
00370 os << size() << endl;
00371 for (int i=1; i<=size(); i++) {
00372 member(i)->write(os);
00373 os << endl;
00374 }
00375 os << endl;
00376 return OK;
00377 }
00378
00379
00380 template <class T, class KEY>
00381 int AbstractHeap<T,KEY>::read(istream& is)
00382 {
00383 clear();
00384 int Size;
00385 is >> Size;
00386 for (int i=1; i<=Size; i++) {
00387 T* item;
00388 item->read(is);
00389 add(item);
00390 }
00391 return OK;
00392 }
00393
00394
00395
00396
00397
00398
00399
00400
00401 template <class T, class KEY>
00402 T* AbstractHeap<T,KEY>::find(KEY& key)
00403 {
00404 for (int i=1; i<= size(); i++)
00405 if (member(i)->compare(key) == 0)
00406 return member(i);
00407
00408 return 0;
00409 }
00410
00411
00412 template <class T, class KEY>
00413 void AbstractHeap<T,KEY>::clear()
00414 {
00415 bool status;
00416 while (size()>0) {
00417 remove(top(),status);
00418 if (!status)
00419 ErrAbort("AbstractHeap<T,KEY>::clear - problem removing the root of the heap.");
00420 }
00421 }
00422
00423
00424 #endif