Grafalgo
Library of useful data structures and algorithms
/Users/jst/src/grafalgo/cpp/dataStructures/searchTrees/DkBstSet.cpp
Go to the documentation of this file.
00001 
00008 #include "DkBstSet.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 kee1(x) node[x].kee
00014 #define dmin(x) dmin[x]
00015 #define dkey(x) dkey[x]
00016 
00017 namespace grafalgo {
00018 
00022 DkBstSet::DkBstSet(int size) : SaBstSet(size) {
00023         makeSpace(size);
00024 }
00025 
00027 DkBstSet::~DkBstSet() { freeSpace(); }
00028 
00032 void DkBstSet::makeSpace(int size) {
00033         try {
00034                 dmin = new keytyp[size+1]; dkey = 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         nn = size; clear();
00043 }
00044 
00046 void DkBstSet::freeSpace() {
00047         delete [] dmin; delete [] dkey;
00048 }
00049 
00051 void DkBstSet::clear() {
00052         SaBstSet::clear();
00053         for (int i = 0; i <= n(); i++) dmin(i) = dkey(i) = 0; 
00054 }
00055 
00059 void DkBstSet::resize(int size) {
00060         freeSpace();
00061         SaBstSet::resize(size);
00062         try { makeSpace(size); } catch(OutOfSpaceException e) {
00063                 string s; s = "DkBstSet::resize::" + e.toString(s);
00064                 throw OutOfSpaceException(s);
00065         }
00066 }
00067 
00072 void DkBstSet::expand(int size) {
00073         if (size <= n()) return;
00074         DkBstSet old(this->n()); old.copyFrom(*this);
00075         resize(size); this->copyFrom(old);
00076 }
00080 void DkBstSet::copyFrom(const DkBstSet& source) {
00081         if (&source == this) return;
00082         if (source.n() > n()) resize(source.n());
00083         else clear();
00084 
00085         SaBstSet::copyFrom(source);
00086         for (index x = 1; x <= n(); x++) {
00087                 dmin(x) = source.dmin[x]; dkey(x) = source.dkey[x];
00088         }
00089 }
00090 
00095 keytyp DkBstSet::key2(index i) {
00096         assert(1 <= i && i <= n());
00097         splay(i);
00098         return dmin(i) + dkey(i);
00099 }
00100 
00105 void DkBstSet::rotate(index x) {
00106         index y = p(x); if (y == 0) return;
00107         index a, b, c;
00108         if (x == left(y)) { a = left(x);  b = right(x); c = right(y); }
00109         else              { a = right(x); b = left(x);  c = left(y);  }
00110         SaBstSet::rotate(x);
00111 
00112         dmin(a) += dmin(x); dmin(b) += dmin(x);
00113 
00114         dkey(x) = dkey(x) + dmin(x);
00115         keytyp dmx = dmin(x);
00116         dmin(x) = dmin(y);
00117 
00118         dmin(y) = dkey(y);
00119         if (b != 0) dmin(y) = min(dmin(y),dmin(b)+dmx);
00120         if (c != 0) dmin(y) = min(dmin(y),dmin(c));
00121         dkey(y) = dkey(y) - dmin(y);
00122 
00123         dmin(b) -= dmin(y); dmin(c) -= dmin(y);
00124 }
00125 
00132 index DkBstSet::access(keytyp k, bst t)  {
00133         assert (0 <= t && t <= n());
00134         if (t == 0) return 0;
00135         index v = 0;
00136         while (true) {
00137                 if (k < kee1(t)) {
00138                         if (left(t) == 0) break;
00139                         t = left(t);
00140                 } else {
00141                         v = t;
00142                         if (right(t) == 0) break;
00143                         t = right(t);
00144                 }
00145         }
00146         splay(t);
00147         return (kee1(t) == k ? t : v);
00148 }
00149 
00155 index DkBstSet::insert(index i, bst t) {
00156         assert (1 <= i && i <= n() && 1 <= t && t <= n() && i != t);
00157         assert (left(0) == 0 && right(0) == 0 && p(0) == 0);
00158         bst x = t; keytyp key2i = dmin(i);
00159         // save key2 value of i and correct dmin, dkey values
00160         // of i after splay brings it to the root
00161         while (true) {
00162                      if (kee1(i) < kee1(x) &&  left(x) != 0) x = left(x);
00163                 else if (kee1(i) > kee1(x) && right(x) != 0) x = right(x);
00164                 else break;
00165         }
00166              if (kee1(i) < kee1(x))  left(x) = i;
00167         else if (kee1(i) > kee1(x)) right(x) = i;
00168         else Util::fatal("DkBstSet::insert: inserting node with duplicate key");
00169         p(i) = x;
00170         splay(i); // note: apparent key value of i is >= that of any node on
00171                   // path back to root; this ensures correct dmin, dkey values
00172                   // assigned to other nodes during rotations
00173         index l = left(i); index r = right(i);
00174         keytyp dmi = key2i;
00175         if (l != 0 && dmin(l) + dmin(i) < dmi) dmi = dmin(l) + dmin(i);
00176         if (r != 0 && dmin(r) + dmin(i) < dmi) dmi = dmin(r) + dmin(i);
00177         if (l != 0) dmin(l) += (dmin(i) - dmi);
00178         if (r != 0) dmin(r) += (dmin(i) - dmi);
00179         dmin(i) = dmi;
00180         dkey(i) = key2i - dmi;
00181         return i;
00182 }
00183 
00190 index DkBstSet::remove(index i, bst t) {
00191         assert(1 <= i && i <= n() && 1 <= t && t <= n());
00192         assert (left(0) == 0 && right(0) == 0 && p(0) == 0);
00193 
00194         // search for i in the tree to determine its key2 value
00195         index x = t; keytyp key2i = 0;
00196         while (x != i) {
00197                 assert(x != 0);
00198                 key2i += dmin(x);
00199                 if (kee1(i) < kee1(x)) x = left(x);
00200                 else x = right(x);
00201         }
00202         key2i += (dmin(i) + dkey(i));
00203 
00204         index j;
00205         if (left(i) == 0 || right(i) == 0) {
00206                 // move the non-null child (if any) into i's position
00207                 j = (left(i) == 0 ? right(i) : left(i));
00208                 if (j != 0) { dmin(j) += dmin(i); p(j) = p(i); }
00209                 if (p(i) != 0) {
00210                              if (i ==  left(p(i)))  left(p(i)) = j;
00211                         else if (i == right(p(i))) right(p(i)) = j;
00212                 }
00213         } else {
00214                 // find first node to the left of i
00215                 for (j = left(i); right(j) != 0; j = right(j)) {}
00216                 // move j up into i's position in tree
00217                 int pi = p(i);
00218                 while (p(j) != i && p(j) != pi) splaystep(j);
00219                 if (p(j) == i) rotate(j);
00220                 // now i is the right child of j and has no left child
00221                 right(j) = right(i); p(right(j)) = j;
00222                 dmin(right(j)) += dmin(i);
00223         }
00224         p(i) = left(i) = right(i) = 0;
00225         dmin(i) = key2i; dkey(i) = 0;
00226         return splay(j);
00227 }
00228 
00236 bst DkBstSet::join(bst t1, index i, bst t2) {
00237         SaBstSet::join(t1,i,t2);
00238         keytyp key2i = dmin(i) + dkey(i);
00239         if (t1 != 0) dmin(i) = min(dmin(i),dmin(t1));
00240         if (t2 != 0) dmin(i) = min(dmin(i),dmin(t2));
00241         dkey(i) = key2i - dmin(i);
00242         if (t1 != 0) dmin(t1) -= dmin(i);
00243         if (t2 != 0) dmin(t2) -= dmin(i);
00244         return i;
00245 }
00246 
00254 BstSet::BstPair DkBstSet::split(index i, bst t) {
00255         BstPair pair = SaBstSet::split(i,t);
00256         if (pair.t1 != 0) dmin(pair.t1) += dmin(i);
00257         if (pair.t2 != 0) dmin(pair.t2) += dmin(i);
00258         dmin(i) += dkey(i); dkey(i) = 0;
00259         return pair;
00260 }
00261 
00267 string& DkBstSet::node2string(index i, string& s) const {
00268         s = "";
00269         if (i == 0) return s;
00270         stringstream ss;
00271         ss << Adt::item2string(i,s);
00272         if (p(i) == 0) ss << "*";
00273         ss << ":" << kee1(i) << ":" << dmin(i) << ":" << dkey(i);
00274         s = ss.str();
00275         return s;
00276 }
00277 
00278 } // ends namespace
 All Classes Files Functions Variables Typedefs Friends