Grafalgo
Library of useful data structures and algorithms
|
00001 00009 #include "LlheapSet.h" 00010 00011 #define kee(x) node[x].kee 00012 #define rank(x) node[x].rank 00013 #define left(x) node[x].left 00014 #define right(x) node[x].right 00015 00016 #define deleted(x)((x > n()) || (delf != 0 && (*delf)(x))) 00017 00018 namespace grafalgo { 00019 00027 LlheapSet::LlheapSet(int size, delftyp f) : LheapSet(2*size) { 00028 makeSpace(size); delf = f; 00029 } 00030 00032 LlheapSet::~LlheapSet() { freeSpace(); } 00033 00037 void LlheapSet::makeSpace(int size) { 00038 try { 00039 tmplst = new List(size); 00040 } catch (std::bad_alloc e) { 00041 stringstream ss; 00042 ss << "makeSpace:: insufficient space for " 00043 << size << "index values"; 00044 string s = ss.str(); 00045 throw OutOfSpaceException(s); 00046 } 00047 nn = size; clear(); 00048 } 00049 00051 void LlheapSet::freeSpace() { delete tmplst; } 00052 00054 void LlheapSet::copyFrom(const LlheapSet& source) { 00055 if (&source == this) return; 00056 if (source.n() > n()) resize(source.n()); 00057 else clear(); 00058 for (index i = n()+1; i <= 2*n() ; i++) 00059 node[i] = source.node[i]; 00060 dummy = source.dummy; delf = source.delf; 00061 } 00062 00067 void LlheapSet::resize(int size) { 00068 freeSpace(); LheapSet::resize(size); 00069 try { makeSpace(size); } catch(OutOfSpaceException e) { 00070 string s; s = "LlheapSet::resize::" + e.toString(s); 00071 throw OutOfSpaceException(s); 00072 } 00073 } 00074 00079 void LlheapSet::expand(int size) { 00080 if (size <= n()) return; 00081 LlheapSet old(this->n()); old.copyFrom(*this); 00082 resize(size); this->copyFrom(old); 00083 } 00084 00086 void LlheapSet::clear() { 00087 // build list of dummy nodes linked using left pointers 00088 LheapSet::clear(); tmplst->clear(); 00089 for (index i = n()+1; i <= 2*n() ; i++) left(i) = i+1; 00090 dummy = n()+1; left(2*n()) = 0; 00091 rank(0) = 0; left(0) = right(0) = 0; 00092 } 00093 00100 lheap LlheapSet::lmeld(lheap h1, lheap h2) { 00101 assert(0 <= h1 && h1 <= 2*n() && 0 <= h2 && h2 <= 2*n() && dummy != 0); 00102 int i = dummy; dummy = left(dummy); 00103 left(i) = h1; right(i) = h2; 00104 return i; 00105 } 00106 00112 lheap LlheapSet::insert(index i, lheap h) { 00113 assert(0 <= i && i <= n() && 0 <= h && h <= 2*n()); 00114 assert(left(i) == 0 && right(i) == 0 && rank(i) ==1); 00115 tmplst->clear(); purge(h,*tmplst); h = heapify(*tmplst); 00116 return meld(i,h); 00117 } 00118 00123 index LlheapSet::findmin(lheap h) { 00124 assert(0 <= h && h <= 2*n()); 00125 tmplst->clear(); purge(h,*tmplst); return heapify(*tmplst); 00126 } 00127 00133 lheap LlheapSet::heapify(List& hlst) { 00134 if (hlst.empty()) return 0; 00135 while (hlst.get(2) != 0) { 00136 lheap h = meld(hlst.get(1), hlst.get(2)); 00137 hlst.removeFirst(); hlst.removeFirst(); hlst.addLast(h); 00138 } 00139 return hlst.first(); 00140 } 00141 00150 void LlheapSet::purge(lheap h, List& hlst) { 00151 if (h == 0) return; 00152 if (!deleted(h)) { 00153 hlst.addLast(h); 00154 } else { 00155 purge(left(h),hlst); purge(right(h),hlst); 00156 if (h > n()) { 00157 left(h) = dummy; dummy = h; right(h) = 0; 00158 } else { 00159 left(h) = right(h) = 0; rank(h) = 1; 00160 } 00161 } 00162 } 00163 00168 lheap LlheapSet::makeheap(List& hlst) { 00169 assert(hlst.n() <= tmplst->n()); 00170 tmplst->clear(); 00171 for (int i = hlst.first(); i != 0; i = hlst.next(i)) 00172 tmplst->addLast(i); 00173 return heapify(*tmplst); 00174 } 00175 00180 string& LlheapSet::toString(string& s) const { 00181 s = ""; 00182 int i; bool *isroot = new bool[n()+1]; 00183 for (i = 1; i <= n(); i++) isroot[i] = true; 00184 for (i = 1; i <= n(); i++) 00185 isroot[left(i)] = isroot[right(i)] = false; 00186 for (i = 1; i <= n(); i++) { 00187 if (isroot[i] && (left(i) != 0 || right(i) != 0)) { 00188 string s1; s += heap2string(i,s1) + "\n"; 00189 } 00190 } 00191 delete [] isroot; 00192 return s; 00193 } 00194 00201 string& LlheapSet::heap2string(lheap h, bool isroot, string& s) const { 00202 s = ""; 00203 if (h == 0) return s; 00204 stringstream ss; 00205 if (left(h) == 0 && right(h) == 0) { 00206 if (deleted(h)) ss << "- "; 00207 else ss << item2string(h,s) << ":" << kee(h) << "," << rank(h); 00208 } else { 00209 ss << "("; 00210 if (left(h) != 0) ss << heap2string(left(h),false,s) << " "; 00211 if (deleted(h)) { 00212 ss << "- "; 00213 } else { 00214 ss << item2string(h,s) << ":" << kee(h) << "," 00215 << rank(h); 00216 if (isroot) ss << "*"; 00217 } 00218 if (right(h) != 0) ss << " " << heap2string(right(h),false,s); 00219 ss << ")"; 00220 } 00221 s = ss.str(); 00222 return s; 00223 } 00224 00225 } // ends namespace