Grafalgo
Library of useful data structures and algorithms
|
00001 00008 #include "BstSet.h" 00009 00010 #define left(x) node[x].left 00011 #define right(x) node[x].right 00012 #define p(x) node[x].p 00013 #define kee(x) node[x].kee 00014 00015 namespace grafalgo { 00016 00020 BstSet::BstSet(int size) : Adt(size) { 00021 makeSpace(size); 00022 } 00023 00025 BstSet::~BstSet() { freeSpace(); } 00026 00030 void BstSet::makeSpace(int size) { 00031 try { 00032 node = new BstNode[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 BstSet::freeSpace() { 00045 delete [] node; 00046 } 00047 00049 void BstSet::clear() { 00050 for (index i = 0; i <= n(); i++) { 00051 left(i) = right(i) = p(i) = kee(i) = 0; 00052 } 00053 } 00054 00058 void BstSet::resize(int size) { 00059 freeSpace(); 00060 try { makeSpace(size); } catch(OutOfSpaceException e) { 00061 string s; s = "BstSet::resize::" + e.toString(s); 00062 throw OutOfSpaceException(s); 00063 } 00064 } 00065 00070 void BstSet::expand(int size) { 00071 if (size <= n()) return; 00072 BstSet old(this->n()); old.copyFrom(*this); 00073 resize(size); this->copyFrom(old); 00074 } 00078 void BstSet::copyFrom(const BstSet& source) { 00079 if (&source == this) return; 00080 if (source.n() > n()) resize(source.n()); 00081 else clear(); 00082 00083 for (index x = 1; x <= n(); x++) { 00084 node[x] = source.node[x]; 00085 } 00086 } 00087 00092 void BstSet::rotate(index x) { 00093 index y = p(x); 00094 if (y == 0) return; 00095 p(x) = p(y); 00096 if (y == left(p(y))) left(p(x)) = x; 00097 else if (y == right(p(y))) right(p(x)) = x; 00098 if (x == left(y)) { 00099 left(y) = right(x); 00100 if (left(y) != 0) p(left(y)) = y; 00101 right(x) = y; 00102 } else { 00103 right(y) = left(x); 00104 if (right(y) != 0) p(right(y)) = y; 00105 left(x) = y; 00106 } 00107 p(y) = x; 00108 } 00109 00115 bst BstSet::find(index i) const { 00116 assert (0 <= i && i <= n()); 00117 while (p(i) != 0) i = p(i); 00118 return i; 00119 } 00120 00127 index BstSet::access(keytyp k, bst& t) const { 00128 assert (0 <= t && t <= n()); 00129 index x = t; 00130 while (x != 0 && k != kee(x)) { 00131 if (k < kee(x)) x = left(x); 00132 else x = right(x); 00133 } 00134 return x; 00135 } 00136 00142 index BstSet::first(bst t) const { 00143 while (left(t) != 0) t = left(t); 00144 return t; 00145 } 00146 00152 index BstSet::last(bst t) const { 00153 while (right(t) != 0) t = right(t); 00154 return t; 00155 } 00156 00162 index BstSet::suc(index i) const { 00163 if (right(i) != 0) { 00164 for (i = right(i); left(i) != 0; i = left(i)) {} 00165 } else { 00166 index c = i; i = p(i); 00167 while (i != 0 && right(i) == c) { c = i; i = p(i); } 00168 } 00169 return i; 00170 } 00171 00177 index BstSet::pred(index i) const { 00178 if (left(i) != 0) { 00179 for (i = left(i); right(i) != 0; i = right(i)) {} 00180 } else { 00181 index c = i; i = p(i); 00182 while (i != 0 && left(i) == c) { c = i; i = p(i); } 00183 } 00184 return i; 00185 } 00186 00193 bool BstSet::insert(index i, bst& t) { 00194 assert (1 <= i && i <= n() && 0 <= t && t <= n()); 00195 assert (left(0) == 0 && right(0) == 0 && p(0) == 0); 00196 if (t == 0) { t = i; return true; } 00197 index x = t; 00198 while (1) { 00199 if (kee(i) < kee(x) && left(x) != 0) x = left(x); 00200 else if (kee(i) > kee(x) && right(x) != 0) x = right(x); 00201 else break; 00202 } 00203 if (kee(i) < kee(x)) left(x) = i; 00204 else if (kee(i) > kee(x)) right(x) = i; 00205 else return false; 00206 p(i) = x; 00207 return true; 00208 } 00209 00216 void BstSet::swap(index i, index j) { 00217 assert(1 <= i && i <= n() && 1 <= j && j <= n() && j != p(i)); 00218 00219 // save pointer fields for items i and j 00220 index li,ri,pi,lj,rj,pj; 00221 li = left(i); ri = right(i); pi = p(i); 00222 lj = left(j); rj = right(j); pj = p(j); 00223 00224 // fixup fields in i's neighbors 00225 if (li != 0) p(li) = j; 00226 if (ri != 0) p(ri) = j; 00227 if (pi != 0) { 00228 if (i == left(pi)) left(pi) = j; 00229 else right(pi) = j; 00230 } 00231 // fixup fields in j's neighbors 00232 if (lj != 0) p(lj) = i; 00233 if (rj != 0) p(rj) = i; 00234 if (pj != 0) { 00235 if (j == left(pj)) left(pj) = i; 00236 else right(pj) = i; 00237 } 00238 00239 // update fields in items i and j 00240 left(i) = lj; right(i) = rj; p(i) = pj; 00241 left(j) = li; right(j) = ri; p(j) = pi; 00242 00243 // final fixup for the case that i was originally the parent of j 00244 if (j == li) { left(j) = i; p(i) = j; } 00245 else if (j == ri) { right(j) = i; p(i) = j; } 00246 } 00247 00253 void BstSet::remove(index i, bst& t) { 00254 assert(1 <= i && i <= n() && 1 <= t && t <= n()); 00255 index c = (left(t) != 0 ? left(t) : right(t)); 00256 index j; 00257 if (left(i) != 0 && right(i) != 0) { 00258 for (j = left(i); right(j) != 0; j = right(j)) {} 00259 swap(i,j); 00260 } 00261 // now, i has at most one child 00262 j = (left(i) != 0 ? left(i) : right(i)); 00263 // j is now the index of the only child that could be non-null 00264 if (j != 0) p(j) = p(i); 00265 if (p(i) != 0) { 00266 if (i == left(p(i))) left(p(i)) = j; 00267 else if (i == right(p(i))) right(p(i)) = j; 00268 } 00269 p(i) = left(i) = right(i) = 0; 00270 if (i == t) t = (p(c) == 0 ? c : p(c)); 00271 return; 00272 } 00273 00281 bst BstSet::join(bst t1, index i, bst t2) { 00282 assert(0 <= t1 && t1 <= n() && 1 <= i && i <= n() && 00283 0 <= t2 && t2 <= n()); 00284 left(i) = t1; right(i) = t2; 00285 if (t1 != 0) p(t1) = i; 00286 if (t2 != 0) p(t2) = i; 00287 return i; 00288 } 00289 00297 BstSet::BstPair BstSet::split(index i, bst s) { 00298 assert(1 <= i && i <= n() && 1 <= s && s <= n()); 00299 bst y = i; BstPair pair(left(i),right(i)); 00300 for (bst x = p(y); x != 0; x = p(y)) { 00301 if (y == left(x)) pair.t2 = join(pair.t2,x,right(x)); 00302 else if (y == right(x)) pair.t1 = join(left(x),x,pair.t1); 00303 y = x; 00304 } 00305 left(i) = right(i) = p(i) = 0; 00306 p(pair.t1) = p(pair.t2) = 0; 00307 return pair; 00308 } 00309 00315 string& BstSet::node2string(index i, string& s) const { 00316 stringstream ss; 00317 s = ""; 00318 if (i == 0) return s; 00319 ss << Adt::item2string(i,s); 00320 if (p(i) == 0) ss << "*"; 00321 ss << ":" << key(i); 00322 s = ss.str(); 00323 return s; 00324 } 00325 00331 string& BstSet::bst2string(bst t, string& s) const { 00332 s = ""; 00333 if (t == 0) return s; 00334 string s1; 00335 if (left(t) != 0) s += "(" + bst2string(left(t),s1) + ") "; 00336 s += node2string(t,s1); 00337 if (right(t) != 0) s += " (" + bst2string(right(t),s1) + ")"; 00338 return s; 00339 } 00340 00346 string& BstSet::toString(string& s) const { 00347 string s1; 00348 s = ""; 00349 for (index i = 1; i <= n(); i++) { 00350 if (p(i) == 0 && (left(i) != 0 || right(i) != 0)) { 00351 s += bst2string(i,s1) + "\n"; 00352 } 00353 } 00354 return s; 00355 } 00356 00357 } // ends namespace