00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 # ifndef TPL_RB_TREE_H
00045 # define TPL_RB_TREE_H
00046
00047 # include <ahFunction.H>
00048 # include <tpl_arrayStack.H>
00049 # include <tpl_binNodeUtils.H>
00050 # include <rbNode.H>
00051
00052 using namespace Aleph;
00053
00054 namespace Aleph {
00055
00075 template <template <typename> class NodeType, typename Key, class Compare>
00076 class Gen_Rb_Tree
00077 {
00078
00079 public:
00080
00081 typedef NodeType<Key> Node;
00082
00083
00084 private:
00085
00086 Node head_node;
00087 Node * head;
00088 Node *& root;
00089 FixedStack<Node*, Node::MaxHeight> rb_stack;
00090 Node * search_and_stack_rb(const Key & key)
00091 {
00092 Node * p = root;
00093 rb_stack.push(head);
00094
00095 do
00096 {
00097 rb_stack.push(p);
00098
00099 if (Compare () (key, KEY(p)))
00100 p = LLINK(p);
00101 else if (Compare () (KEY(p), key))
00102 p = RLINK(p);
00103 else
00104 return p;
00105 }
00106 while (p != Node::NullPtr);
00107
00108 return rb_stack.top();
00109 }
00110 void fix_red_condition(Node * p)
00111 {
00112
00113 I(COLOR(p) == RED);
00114
00115 while (p != root)
00116 {
00117 Node * pp = rb_stack.pop();
00118
00119 if (COLOR(pp) == BLACK)
00120 break;
00121
00122 if (root == pp)
00123 {
00124 COLOR(root) = BLACK;
00125 break;
00126 }
00127
00128 Node * ppp = rb_stack.pop();
00129 Node * spp = LLINK(ppp) == pp ? RLINK(ppp) : LLINK(ppp);
00130
00131 if (COLOR(spp) == RED)
00132 {
00133 COLOR(ppp) = RED;
00134 COLOR(pp) = BLACK;
00135 COLOR(spp) = BLACK;
00136 p = ppp;
00137 continue;
00138 }
00139
00140 Node *pppp = rb_stack.pop();
00141
00142 if (LLINK(pp) == p and LLINK(ppp) == pp)
00143 {
00144 rotate_to_right(ppp, pppp);
00145 COLOR(pp) = BLACK;
00146 }
00147 else if (RLINK(pp) == p and RLINK(ppp) == pp)
00148 {
00149 rotate_to_left(ppp, pppp);
00150 COLOR(pp) = BLACK;
00151 }
00152 else
00153 {
00154 if (RLINK(pp) == p)
00155 {
00156 rotate_to_left(pp, ppp);
00157 rotate_to_right(ppp, pppp);
00158 }
00159 else
00160 {
00161 rotate_to_right(pp, ppp);
00162 rotate_to_left(ppp, pppp);
00163 }
00164 COLOR(p) = BLACK;
00165 }
00166 COLOR(ppp) = RED;
00167
00168 break;
00169 }
00170 rb_stack.empty();
00171 }
00172 void find_succ_and_swap(Node * p, Node *& pp)
00173 {
00174 Node *& ref_rb_stack = rb_stack.top();
00175
00176
00177 Node * fSucc = p;
00178 Node * succ = RLINK(p);
00179
00180 rb_stack.push(succ);
00181 while (LLINK(succ) != Node::NullPtr)
00182 {
00183 fSucc = succ;
00184 succ = LLINK(succ);
00185 rb_stack.push(succ);
00186 }
00187
00188 ref_rb_stack = succ;
00189 rb_stack.top() = p;
00190
00191 if (LLINK(pp) == p)
00192 LLINK(pp) = succ;
00193 else
00194 RLINK(pp) = succ;
00195
00196 LLINK(succ) = LLINK(p);
00197 LLINK(p) = Node::NullPtr;
00198
00199 if (RLINK(p) == succ)
00200 {
00201 RLINK(p) = RLINK(succ);
00202 RLINK(succ) = p;
00203 pp = succ;
00204 }
00205 else
00206 {
00207 Node *succr = RLINK(succ);
00208 RLINK(succ) = RLINK(p);
00209 LLINK(fSucc) = p;
00210 RLINK(p) = succr;
00211 pp = fSucc;
00212 }
00213
00214 Aleph::swap(COLOR(succ), COLOR(p));
00215 }
00216
00217 void fix_black_condition(Node * p)
00218 {
00219 if (COLOR(p) == RED)
00220 {
00221 COLOR(p) = BLACK;
00222 return;
00223 }
00224
00225 Node * pp = rb_stack.popn(2);
00226
00227 while (p != root)
00228 {
00229
00230 I(LLINK(pp) == p or RLINK(pp) == p);
00231 I(LLINK(rb_stack.top()) == pp or RLINK(rb_stack.top()) == pp);
00232
00233 Node * sp = LLINK(pp) == p ? RLINK(pp) : LLINK(pp);
00234
00235 if (COLOR(sp) == RED)
00236 {
00237 Node *& ppp = rb_stack.top();
00238
00239 if (LLINK(pp) == p)
00240 {
00241 sp = LLINK(sp);
00242 ppp = rotate_to_left(pp, ppp);
00243 }
00244 else
00245 {
00246 sp = RLINK(sp);
00247 ppp = rotate_to_right(pp, ppp);
00248 }
00249
00250 COLOR(ppp) = BLACK;
00251 COLOR(pp) = RED;
00252 }
00253
00254 Node * np, * snp;
00255 if (LLINK(pp) == p)
00256 {
00257 np = RLINK(sp);
00258 snp = LLINK(sp);
00259 }
00260 else
00261 {
00262 np = LLINK(sp);
00263 snp = RLINK(sp);
00264 }
00265
00266 if (COLOR(np) == RED)
00267 {
00268 Node * ppp = rb_stack.top();
00269
00270 if (RLINK(sp) == np)
00271 rotate_to_left(pp, ppp);
00272 else
00273 rotate_to_right(pp, ppp);
00274
00275 COLOR(sp) = COLOR(pp);
00276 COLOR(pp) = BLACK;
00277 COLOR(np) = BLACK;
00278 return;
00279 }
00280
00281 if (COLOR(snp) == RED)
00282 {
00283 Node * ppp = rb_stack.top();
00284
00285 if (LLINK(sp) == snp)
00286 {
00287 rotate_to_right(sp, pp);
00288 rotate_to_left(pp, ppp);
00289 }
00290 else
00291 {
00292 rotate_to_left(sp, pp);
00293 rotate_to_right(pp, ppp);
00294 }
00295
00296 COLOR(snp) = COLOR(pp);
00297 COLOR(pp) = BLACK;;
00298 return;
00299 }
00300
00301 if (color(pp) == RED)
00302 {
00303 COLOR(pp) = BLACK;
00304 COLOR(sp) = RED;;
00305 return;
00306 }
00307
00308
00309
00310 COLOR(sp) = RED;
00311 p = pp;
00312 pp = rb_stack.pop();
00313 }
00314 }
00315
00316
00317 public:
00318
00319
00321 Gen_Rb_Tree() : head(&head_node), root(head_node.getR()) { }
00322
00324 virtual ~Gen_Rb_Tree() { }
00325
00329 Node * search(const Key & key)
00330 {
00331 Node * retVal = Aleph::searchInBinTree<Node, Compare>(root, key);
00332
00333 return retVal == Node::NullPtr ? NULL : retVal;
00334 }
00335
00337 Node *& getRoot() { return root; }
00342 Node * insert(Node * p)
00343 {
00344
00345 I(COLOR(p) == RED);
00346
00347 if (root == Node::NullPtr)
00348 return root = p;
00349
00350 Node * q = search_and_stack_rb(KEY(p));
00351
00352 if (Compare () (KEY(p), KEY(q)))
00353 LLINK(q) = p;
00354 else if (Compare () (KEY(q), KEY(p)))
00355 RLINK(q) = p;
00356 else
00357 {
00358 rb_stack.empty();
00359
00360 return NULL;
00361 }
00362
00363 fix_red_condition(p);
00364
00365 return p;
00366 }
00371 Node* remove(const Key & key)
00372 {
00373 if (root == Node::NullPtr)
00374 return NULL;
00375
00376 Node * q = search_and_stack_rb(key);
00377
00378 if (no_equals<Key, Compare> (KEY(q), key))
00379 {
00380 rb_stack.empty();
00381 return NULL;
00382 }
00383
00384 Node * pq = rb_stack.top(1);
00385 Node * p;
00386
00387 repeat:
00388
00389 if (LLINK(q) == Node::NullPtr)
00390 {
00391 if (LLINK(pq) == q)
00392 p = LLINK(pq) = RLINK(q);
00393 else
00394 p = RLINK(pq) = RLINK(q);
00395
00396 goto end;
00397 }
00398
00399 if (RLINK(q) == Node::NullPtr)
00400 {
00401 if (LLINK(pq) == q)
00402 p = LLINK(pq) = LLINK(q);
00403 else
00404 p = RLINK(pq) = LLINK(q);
00405
00406 goto end;
00407 }
00408
00409 find_succ_and_swap(q, pq);
00410
00411 goto repeat;
00412
00413 end:
00414 if (COLOR(q) == BLACK)
00415 fix_black_condition(p);
00416
00417 q->reset();
00418 rb_stack.empty();
00419
00420 return q;
00421 }
00422 };
00423
00438 template <typename Key, class Compare = Aleph::less<Key> >
00439 struct Rb_Tree : public Gen_Rb_Tree<RbNode, Key, Compare>
00440 { };
00441
00457 template <typename Key, class Compare = Aleph::less<Key> >
00458 struct Rb_Tree_Vtl : public Gen_Rb_Tree<RbNodeVtl, Key, Compare>
00459 { };
00460
00461 }
00462
00463 # endif // TPL_RB_TREE_H
00464