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_AVL_H
00045 # define TPL_AVL_H
00046
00047 # include <ahFunction.H>
00048 # include <tpl_arrayStack.H>
00049 # include <avlNode.H>
00050 # include <tpl_binNodeUtils.H>
00051
00052 using namespace Aleph;
00053
00054 namespace Aleph {
00055
00075 template <template <typename> class NodeType, typename Key, class Compare>
00076 class Gen_Avl_Tree
00077 {
00078
00079 public:
00080
00081 typedef NodeType<Key> Node;
00082
00083 private:
00084
00085 FixedStack<Node *, Node::MaxHeight> avl_stack;
00086 Node head_node;
00087 Node * head_ptr;
00088 Node *& root;
00089 Compare cmp;
00090 bool avl_stack_empty() { return avl_stack.top() == head_ptr; }
00091
00092 void clean_avl_stack() { avl_stack.popn (avl_stack.size() - 1); }
00093 Node * search_and_stack_avl(const Key & key)
00094 {
00095
00096 I(avl_stack_empty());
00097
00098 Node * p = root;
00099
00100 do
00101 {
00102 avl_stack.push(p);
00103
00104 if (cmp(key, KEY(p)))
00105 p = LLINK(p);
00106 else if (cmp(KEY(p), key))
00107 p = RLINK(p);
00108 else
00109 return p;
00110 }
00111 while (p != Node::NullPtr);
00112
00113 return avl_stack.top();
00114 }
00115 static Node * rotateLeft(Node * p)
00116 {
00117 I(DIFF(p) == 2);
00118 I(RLINK(p) != Node::NullPtr);
00119
00120 Node * q = RLINK(p);
00121 RLINK(p) = LLINK(q);
00122 LLINK(q) = p;
00123
00124 if (DIFF(q) == 0)
00125 {
00126 DIFF(q) = -1;
00127 DIFF(p) = 1;
00128 }
00129 else
00130 DIFF(q) = DIFF(p) = 0;
00131
00132 return q;
00133 }
00134
00135 static Node * rotateRight(Node * p)
00136 {
00137 I(DIFF(p) == -2);
00138 I(LLINK(p) != Node::NullPtr);
00139
00140 Node * q = LLINK(p);
00141 LLINK(p) = RLINK(q);
00142 RLINK(q) = p;
00143
00144 if (DIFF(q) == 0)
00145 {
00146 DIFF(q) = 1;
00147 DIFF(p) = -1;
00148 }
00149 else
00150 DIFF(q) = DIFF(p) = 0;
00151
00152 return q;
00153 }
00154 static Node * doubleRotateLeft(Node * p)
00155 {
00156 I(DIFF(p) == 2 or DIFF(p) == -2);
00157 I(RLINK(p) != Node::NullPtr and LLINK(RLINK(p)) != Node::NullPtr);
00158
00159 Node * q = RLINK(p);
00160 Node * r = LLINK(q);
00161 RLINK(p) = LLINK(r);
00162 LLINK(q) = RLINK(r);
00163 LLINK(r) = p;
00164 RLINK(r) = q;
00165
00166 unsigned char b;
00167 unsigned char c;
00168
00169
00170 if (DIFF(r) == 1)
00171 {
00172 c = 1;
00173 b = 0;
00174 }
00175 else if (DIFF(r) == -1)
00176 {
00177 c = 0;
00178 b = 1;
00179 }
00180 else
00181 c = b = 1;
00182
00183
00184 DIFF(r) = 0;
00185 DIFF(p) = b - 1;
00186 DIFF(q) = 1 - c;
00187
00188 return r;
00189 }
00190
00191 static Node * doubleRotateRight(Node * p)
00192 {
00193 I(DIFF(p) == 2 or DIFF(p) == -2);
00194 I(LLINK(p) != Node::NullPtr and
00195 RLINK(LLINK(p)) != Node::NullPtr);
00196
00197 Node * q = LLINK(p);
00198 Node * r = RLINK(q);
00199 LLINK(p) = RLINK(r);
00200 RLINK(q) = LLINK(r);
00201 RLINK(r) = p;
00202 LLINK(r) = q;
00203
00204 unsigned char b;
00205 unsigned char c;
00206
00207
00208 if (DIFF(r) == 1)
00209 {
00210 c = 1;
00211 b = 0;
00212 }
00213 else if (DIFF(r) == -1)
00214 {
00215 c = 0;
00216 b = 1;
00217 }
00218 else
00219 c = b = 1;
00220
00221
00222 DIFF(r) = 0;
00223 DIFF(p) = 1 - c;
00224 DIFF(q) = b - 1;
00225
00226 return r;
00227 }
00228 enum Rotation_Type
00229 { ROTATE_LEFT, ROTATE_RIGHT, DOUBLE_ROTATE_LEFT, DOUBLE_ROTATE_RIGHT };
00230 static Rotation_Type rotation_type(Node * p)
00231 {
00232
00233 I(DIFF(p) == 2 or DIFF(p) == -2);
00234
00235 Node * pc;
00236
00237 if (DIFF(p) == 2)
00238 {
00239 pc = RLINK(p);
00240 if (DIFF(pc) == 1 or DIFF(pc) == 0)
00241 return ROTATE_LEFT;
00242
00243 return DOUBLE_ROTATE_LEFT;
00244 }
00245
00246 pc = LLINK(p);
00247 if (DIFF(pc) == -1 or DIFF(pc) == 0)
00248 return ROTATE_RIGHT;
00249
00250 return DOUBLE_ROTATE_RIGHT;
00251 }
00252 static Node * restore_avl(Node * p, Node * pp)
00253 {
00254
00255 I(LLINK(pp) == p or RLINK(pp) == p);
00256 I(DIFF(p) == -2 or DIFF(p) == 2);
00257
00258 Node ** link = LLINK(pp) == p ? &LLINK(pp) : &RLINK(pp);
00259
00260 switch (rotation_type(p))
00261 {
00262 case ROTATE_LEFT: return *link = rotateLeft(p);
00263 case ROTATE_RIGHT: return *link = rotateRight(p);
00264 case DOUBLE_ROTATE_LEFT: return *link = doubleRotateLeft(p);
00265 case DOUBLE_ROTATE_RIGHT: return *link = doubleRotateRight(p);
00266
00267 default:
00268 ERROR("Invalid rotation type");
00269 break;
00270
00271 }
00272 return NULL;
00273 }
00274 void restore_avl_after_insertion(const Key & key)
00275 {
00276 Node *pp = avl_stack.pop();
00277
00278 if (key > KEY(pp))
00279 DIFF(pp)++;
00280 else
00281 DIFF(pp)--;
00282
00283 if (DIFF(pp) == 0)
00284 {
00285 clean_avl_stack();
00286 return;
00287 }
00288
00289 if (avl_stack_empty())
00290 return;
00291
00292 Node *gpp;
00293
00294 do
00295 {
00296 gpp = avl_stack.pop();
00297
00298
00299 if (key > KEY(gpp))
00300 DIFF(gpp)++;
00301 else
00302 DIFF(gpp)--;
00303
00304 if (DIFF(gpp) == 0)
00305 break;
00306 else if (DIFF(gpp) == -2 or DIFF(gpp) == 2)
00307 {
00308 Node *ggpp = avl_stack.pop();
00309 restore_avl(gpp, ggpp);
00310 break;
00311 }
00312 }
00313 while (not avl_stack_empty());
00314
00315 clean_avl_stack();
00316 }
00317 Node* swapWithSuccessor(Node * p, Node *& pp)
00318 {
00319
00320
00321 Node *& ref_to_stack_top = avl_stack.top();
00322
00323
00324 Node *fSucc = p;
00325 Node *succ = RLINK(p);
00326 avl_stack.push(succ);
00327 while (LLINK(succ) != Node::NullPtr)
00328 {
00329 fSucc = succ;
00330 succ = LLINK(succ);
00331 avl_stack.push(succ);
00332 }
00333
00334
00335
00336
00337 ref_to_stack_top = succ;
00338 avl_stack.top() = p;
00339
00340
00341 if (LLINK(pp) == p)
00342 LLINK(pp) = succ;
00343 else
00344 RLINK(pp) = succ;
00345
00346
00347 LLINK(succ) = LLINK(p);
00348 LLINK(p) = Node::NullPtr;
00349
00350
00351 if (RLINK(p) == succ)
00352 {
00353 RLINK(p) = RLINK(succ);
00354 RLINK(succ) = p;
00355 pp = succ;
00356 }
00357 else
00358 {
00359 Node *succr = RLINK(succ);
00360 RLINK(succ) = RLINK(p);
00361 LLINK(fSucc) = p;
00362 RLINK(p) = succr;
00363 pp = fSucc;
00364 }
00365 DIFF(succ) = DIFF(p);
00366
00367 return succ;
00368 }
00369 void restore_avl_after_deletion(const Key & key)
00370 {
00371 Node* pp = avl_stack.top(1);
00372
00373 Node* ppp = avl_stack.popn(3);
00374
00375 while (true)
00376 {
00377 if (key >= KEY(pp))
00378 DIFF(pp)--;
00379 else
00380 DIFF(pp)++;
00381
00382 if (DIFF(pp) == -2 or DIFF(pp) == 2)
00383 pp = restore_avl(pp, ppp);
00384
00385 if (DIFF(pp) != 0 or pp == root)
00386 break;
00387
00388 pp = ppp;
00389 ppp = avl_stack.pop();
00390 }
00391
00392 clean_avl_stack();
00393 }
00394
00395 public:
00396
00398 Gen_Avl_Tree() : head_ptr(&head_node), root(RLINK (head_ptr))
00399 {
00400 avl_stack.push(head_ptr);
00401 }
00402
00404 virtual ~Gen_Avl_Tree() { I(avl_stack_empty()); }
00405
00407 Node *& getRoot() { return root; }
00408
00411 Node * search(const Key& key) const
00412 {
00413 return searchInBinTree<Node, Compare>(root, key);
00414 }
00418 Node * insert(Node * p)
00419 {
00420 if (root == Node::NullPtr)
00421 {
00422 root = p;
00423 return p;
00424 }
00425
00426 Node *pp = search_and_stack_avl(KEY(p));
00427
00428 if (cmp (KEY(p), KEY(pp)))
00429 LLINK (pp) = p;
00430 else if (cmp (KEY(pp), KEY(p)))
00431 RLINK(pp) = p;
00432 else
00433 {
00434 clean_avl_stack();
00435
00436 return NULL;
00437 }
00438
00439 restore_avl_after_insertion(KEY(p));
00440
00441 return p;
00442 }
00446 Node * remove(const Key & key)
00447 {
00448 if (root == Node::NullPtr)
00449 return NULL;
00450
00451 Node * p = search_and_stack_avl(key);
00452
00453 if (no_equals<Key, Compare> (KEY(p), key))
00454 {
00455 clean_avl_stack();
00456
00457 return NULL;
00458 }
00459
00460 Key removed_key = KEY(p);
00461 Node * pp = avl_stack.top(1);
00462
00463 while (true)
00464 {
00465 if (LLINK(p) == Node::NullPtr)
00466 {
00467 if (LLINK(pp) == p)
00468 LLINK(pp) = RLINK(p);
00469 else
00470 RLINK(pp) = RLINK(p);
00471
00472 break;
00473 }
00474
00475 if (RLINK(p) == Node::NullPtr)
00476 {
00477 if (LLINK(pp) == p)
00478 LLINK(pp) = LLINK(p);
00479 else
00480 RLINK(pp) = LLINK(p);
00481
00482 break;
00483 }
00484
00485
00486 Node * succ = swapWithSuccessor(p, pp);
00487 removed_key = KEY(succ);
00488 }
00489
00490 p->reset();
00491
00492
00493 if (pp == head_ptr)
00494 {
00495
00496 clean_avl_stack();
00497
00498 return p;
00499 }
00500
00501 restore_avl_after_deletion(removed_key);
00502
00503 return p;
00504 }
00505 };
00506
00523 template <typename Key, class Compare = Aleph::less<Key> >
00524 class Avl_Tree : public Gen_Avl_Tree<AvlNode, Key, Compare>
00525 { };
00526
00543 template <typename Key, class Compare = Aleph::less<Key> >
00544 class Avl_Tree_Vtl : public Gen_Avl_Tree<AvlNodeVtl, Key, Compare>
00545 { };
00546
00547 }
00548 # endif // TPL_AVL_H
00549