Grafalgo
Library of useful data structures and algorithms
|
00001 00008 #include "Dtrees.h" 00009 00010 #define p(x) parentOf[x] 00011 #define succ(x) successor[x] 00012 00013 namespace grafalgo { 00014 00018 Dtrees::Dtrees(int size) : Adt(size) { 00019 makeSpace(size); 00020 } 00021 00023 Dtrees::~Dtrees() { freeSpace(); } 00024 00028 void Dtrees::makeSpace(int size) { 00029 try { 00030 ps = new PathSet(size); 00031 parentOf = new index[size+1]; 00032 successor = new index[size+1]; 00033 } catch (std::bad_alloc e) { 00034 stringstream ss; 00035 ss << "makeSpace:: insufficient space for " 00036 << size << "index values"; 00037 string s = ss.str(); 00038 throw OutOfSpaceException(s); 00039 } 00040 nn = size; clear(); 00041 } 00042 00044 void Dtrees::freeSpace() { 00045 delete ps; delete [] parentOf; delete [] successor; 00046 } 00047 00049 void Dtrees::clear() { 00050 ps->clear(); 00051 for (index x = 1; x <= n(); x++) { 00052 p(x) = succ(x) = 0; 00053 } 00054 } 00055 00059 void Dtrees::resize(int size) { 00060 freeSpace(); 00061 try { makeSpace(size); } catch(OutOfSpaceException e) { 00062 string s; s = "Dtrees::resize::" + e.toString(s); 00063 throw OutOfSpaceException(s); 00064 } 00065 } 00066 00071 void Dtrees::expand(int size) { 00072 if (size <= n()) return; 00073 Dtrees old(this->n()); old.copyFrom(*this); 00074 resize(size); this->copyFrom(old); 00075 } 00079 void Dtrees::copyFrom(const Dtrees& source) { 00080 if (&source == this) return; 00081 if (source.n() > n()) resize(source.n()); 00082 else clear(); 00083 00084 ps->copyFrom(*(source.ps)); 00085 for (index x = 1; x <= n(); x++) { 00086 p(x) = source.parentOf[x]; 00087 succ(x) = source.successor[x]; 00088 } 00089 } 00090 00097 path Dtrees::expose(index i) { 00098 PathNodePair pnPair(0,i); 00099 while (pnPair.i != 0) pnPair = splice(pnPair); 00100 succ(pnPair.p) = 0; 00101 return pnPair.p; 00102 } 00103 00112 Dtrees::PathNodePair Dtrees::splice(PathNodePair pnPair) { 00113 index w = succ(ps->findpath(pnPair.i)); 00114 PathSet::PathPair pp = ps->split(pnPair.i); 00115 if (pp.p1 != 0) succ(pp.p1) = pnPair.i; 00116 pnPair.p = ps->join(pnPair.p,pnPair.i,pp.p2); pnPair.i = w; 00117 return pnPair; 00118 } 00119 00124 index Dtrees::findroot(index i) { 00125 index x; 00126 x = ps->findtail(expose(i)); 00127 succ(x) = 0; // relies on fact that x is canonical element on return 00128 return x; 00129 } 00130 00136 NodeCostPair Dtrees::findcost(index i) { 00137 NodeCostPair cp = ps->findpathcost(expose(i)); 00138 succ(cp.x) = 0; 00139 return cp; 00140 } 00141 00147 void Dtrees::addcost(index i, cost x) { 00148 ps->addpathcost(expose(i),x); 00149 } 00150 00157 void Dtrees::link(tree t, index i) { 00158 p(t) = i; 00159 succ(ps->join(0,expose(t),expose(i))) = 0; 00160 } 00161 00166 void Dtrees::cut(index i) { 00167 p(i) = 0; 00168 expose(i); 00169 PathSet::PathPair pp = ps->split(i); 00170 succ(i) = 0; 00171 if (pp.p2 != 0) succ(pp.p2) = 0; 00172 return; 00173 } 00174 00180 string& Dtrees::path2string(path q, string& s) const { 00181 string s1; 00182 s = ps->path2string(q,s1); 00183 s += " succ(" + Adt::item2string(q,s1); 00184 s += ")=" + Adt::item2string(succ(q),s1) + "\n"; 00185 return s; 00186 } 00187 00192 string& Dtrees::toString(string& s) const { 00193 string s1; 00194 s = ""; 00195 for (index i = 1; i <= n(); i++) { 00196 index j = ps->findtreeroot(i); 00197 if (i == j) s += path2string(i,s1); 00198 } 00199 return s; 00200 } 00201 00202 } // ends namespace