Grafalgo
Library of useful data structures and algorithms
/Users/jst/src/grafalgo/cpp/dataStructures/searchTrees/BstSet.cpp
Go to the documentation of this file.
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
 All Classes Files Functions Variables Typedefs Friends