Grafalgo
Library of useful data structures and algorithms
|
00001 00009 #include "Dheap.h" 00010 00011 #define p(x) (((x)+(d-2))/d) 00012 #define left(x) (d*((x)-1)+2) 00013 #define right(x) (d*(x)+1) 00014 00015 namespace grafalgo { 00016 00021 Dheap::Dheap(int size, int dd) : Adt(size), d(dd) { 00022 makeSpace(size); 00023 } 00024 00026 Dheap::~Dheap() { freeSpace(); } 00027 00031 void Dheap::makeSpace(int size) { 00032 try { 00033 h = new index[size+1]; pos = new int[size+1]; 00034 kee = new keytyp[size+1]; 00035 } catch (std::bad_alloc e) { 00036 stringstream ss; 00037 ss << "makeSpace:: insufficient space for " 00038 << size << "index values"; 00039 string s = ss.str(); 00040 throw OutOfSpaceException(s); 00041 } 00042 for (int i = 1; i <= size; i++) pos[i] = 0; 00043 h[0] = pos[0] = 0; kee[0] = 0; 00044 hn = 0; nn = size; 00045 } 00046 00048 void Dheap::freeSpace() { delete [] h; delete [] pos; delete [] kee; } 00049 00051 void Dheap::copyFrom(const Dheap& source) { 00052 if (&source == this) return; 00053 if (source.n() > n()) resize(source.n()); 00054 else clear(); 00055 d = source.d; 00056 for (int p = 1; p <= source.hn; p--) { 00057 index x = source.h[p]; 00058 h[p] = x; pos[x] = p; kee[x] = source.key(x); 00059 } 00060 } 00061 00066 void Dheap::resize(int size) { 00067 freeSpace(); 00068 try { makeSpace(size); } catch(OutOfSpaceException e) { 00069 string s; s = "Dheap::resize::" + e.toString(s); 00070 throw OutOfSpaceException(s); 00071 } 00072 } 00073 00078 void Dheap::expand(int size) { 00079 if (size <= n()) return; 00080 Dheap old(this->n(),d); old.copyFrom(*this); 00081 resize(size); this->copyFrom(old); 00082 } 00083 00085 void Dheap::clear() { 00086 for (int x = 1; x <= hn; x++) pos[h[x]] = 0; 00087 hn = 0; 00088 } 00089 00094 void Dheap::insert(index i, keytyp k) { 00095 kee[i] = k; hn++; siftup(i,hn); 00096 } 00097 00101 void Dheap::remove(index i) { 00102 int j = h[hn--]; 00103 if (i != j) { 00104 if (kee[j] <= kee[i]) siftup(j,pos[i]); 00105 else siftdown(j,pos[i]); 00106 } 00107 pos[i] = 0; 00108 } 00109 00115 void Dheap::siftup(index i, int x) { 00116 int px = p(x); 00117 while (x > 1 && kee[i] < kee[h[px]]) { 00118 h[x] = h[px]; pos[h[x]] = x; 00119 x = px; px = p(x); 00120 } 00121 h[x] = i; pos[i] = x; 00122 } 00123 00129 void Dheap::siftdown(index i, int x) { 00130 int cx = minchild(x); 00131 while (cx != 0 && kee[h[cx]] < kee[i]) { 00132 h[x] = h[cx]; pos[h[x]] = x; 00133 x = cx; cx = minchild(x); 00134 } 00135 h[x] = i; pos[i] = x; 00136 } 00137 00144 int Dheap::minchild(int x) { 00145 int y; int minc = left(x); 00146 if (minc > hn) return 0; 00147 for (y = minc + 1; y <= right(x) && y <= hn; y++) { 00148 if (kee[h[y]] < kee[h[minc]]) minc = y; 00149 } 00150 return minc; 00151 } 00152 00157 void Dheap::changekey(index i, keytyp k) { 00158 keytyp ki = kee[i]; kee[i] = k; 00159 if (k == ki) return; 00160 if (k < ki) siftup(i,pos[i]); 00161 else siftdown(i,pos[i]); 00162 } 00163 00168 string& Dheap::toString(string& s) const { 00169 stringstream ss; 00170 for (int i = 1; i <= hn; i++) { 00171 ss << "(" << item2string(h[i],s) << "," << kee[h[i]] << ") "; 00172 if ((i%10) == 0) s += "\n"; 00173 } 00174 if ((hn%10) != 0) s += "\n"; 00175 s = ss.str(); 00176 return s; 00177 } 00178 00179 } // ends namespace