Grafalgo
Library of useful data structures and algorithms
|
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