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_BINNODEUTILS_H
00045 # define TPL_BINNODEUTILS_H
00046
00047 # include <ahFunction.H>
00048 # include <ahPair.H>
00049 # include <tpl_arrayStack.H>
00050 # include <tpl_arrayQueue.H>
00051 # include <tpl_dynArray.H>
00052 # include <tpl_dynDlist.H>
00053 # include <tpl_binNode.H>
00054
00055 using namespace Aleph;
00056 namespace Aleph {
00057
00058 template <class Node> inline static
00059 void __inorder_rec(Node *node, const int& level, int & position,
00060 void (*visitFct)(Node*, int, int))
00061 {
00062 if (node == Node::NullPtr)
00063 return;
00064
00065 __inorder_rec(static_cast<Node*>(LLINK(node)),
00066 level + 1, position, visitFct);
00067 (*visitFct)(node, level, position);
00068 ++position;
00069 __inorder_rec(static_cast<Node*>(RLINK(node)),
00070 level + 1, position, visitFct);
00071 }
00093 template <class Node> inline
00094 int inOrderRec(Node * root, void (*visitFct)(Node*, int, int))
00095 {
00096 int position = 0;
00097
00098 __inorder_rec(root, 0, position, visitFct);
00099
00100 return position;
00101 }
00102 template <class Node> inline static
00103 void __preorder_rec (Node *p, const int & level, int & position,
00104 void (*visitFct)(Node*, int, int))
00105 {
00106 if (p == Node::NullPtr)
00107 return;
00108
00109 (*visitFct)(p, level, position);
00110 ++position;
00111
00112 __preorder_rec(static_cast<Node*>(LLINK(p)),
00113 level + 1, position, visitFct);
00114 __preorder_rec(static_cast<Node*>(RLINK(p)),
00115 level + 1, position, visitFct);
00116 }
00117
00140 template <class Node> inline
00141 int preOrderRec(Node * root, void (*visitFct)(Node*, int, int))
00142 {
00143 int position = 0;
00144
00145 __preorder_rec(root, 0, position, visitFct);
00146
00147 return position;
00148 }
00149
00150 template <class Node> inline static
00151 void __postorder_rec(Node *node, const int & level, int & position,
00152 void (*visitFct)(Node*, int, int))
00153 {
00154 if (node == Node::NullPtr)
00155 return;
00156
00157 __postorder_rec(static_cast<Node*>(LLINK(node)),
00158 level + 1, position, visitFct);
00159 __postorder_rec(static_cast<Node*>(RLINK(node)),
00160 level + 1, position, visitFct);
00161
00162 (*visitFct)(node, level, position);
00163 ++position;
00164 }
00165
00187 template <class Node> inline
00188 int postOrderRec(Node * root, void (*visitFct)(Node*, int, int))
00189 {
00190 int position = 0;
00191
00192 __postorder_rec(root, 0, position, visitFct);
00193
00194 return position;
00195 }
00222 template <class Node> inline
00223 size_t simple_preOrderStack(Node * node, void (*visitFct)(Node *, int, int))
00224 {
00225 if (node == Node::NullPtr)
00226 return 0;
00227
00228 ArrayStack<Node *, Node::MaxHeight> stack;
00229
00230 stack.push(node);
00231
00232 Node * p;
00233
00234 size_t count = 0;
00235
00236 while (not stack.is_empty())
00237 {
00238 p = stack.pop();
00239
00240 (*visitFct) (p, stack.size(), count++);
00241
00242 if (RLINK(p) != Node::NullPtr)
00243 stack.push(RLINK(p));
00244
00245 if (LLINK(p) != Node::NullPtr)
00246 stack.push(LLINK(p));
00247 }
00248
00249 return count;
00250 }
00277 template <class Node> inline
00278 size_t preOrderStack(Node * node, void (*visitFct)(Node *, int, int))
00279 {
00280 if (node == Node::NullPtr)
00281 return 0;
00282
00283 ArrayStack<Node *, Node::MaxHeight> stack;
00284 Node *p = node;
00285
00286 size_t count = 0;
00287
00288 while (true)
00289 {
00290 (*visitFct)(p, stack.size(), count++);
00291
00292 if (LLINK(p) != Node::NullPtr)
00293 {
00294 stack.push(p);
00295 p = LLINK(p);
00296
00297 continue;
00298 }
00299
00300 while (true)
00301 {
00302 if (RLINK(p) != Node::NullPtr)
00303 {
00304 p = RLINK(p);
00305 break;
00306 }
00307
00308 if (stack.is_empty())
00309 return count;
00310
00311 p = stack.pop();
00312 }
00313 }
00314 }
00340 template <class Node> inline
00341 size_t inOrderStack(Node * node, void (*visitFct)(Node *, int, int))
00342 {
00343 if (node == Node::NullPtr)
00344 return 0;
00345
00346 ArrayStack<Node *, Node::MaxHeight> stack;
00347 Node *p = node;
00348
00349 size_t count = 0;
00350
00351 while (true)
00352 {
00353 if (LLINK(p) != Node::NullPtr)
00354 {
00355 stack.push(p);
00356 p = LLINK(p);
00357
00358 continue;
00359 }
00360 while (true)
00361 {
00362 (*visitFct)(p, stack.size(), count++);
00363
00364 if (RLINK(p) != Node::NullPtr)
00365 {
00366 p = RLINK(p);
00367 break;
00368 }
00369
00370 if (stack.is_empty())
00371 return count;
00372
00373 p = stack.pop();
00374 }
00375 }
00376 }
00377 template <class Node> inline
00378 size_t postOrderStack(Node * root, void (*visitFct)(Node *, int, int))
00379 {
00380 if (root == Node::NullPtr)
00381 return 0;
00382
00383 typedef Aleph::pair<Node*, char> Postorder_Pair;
00384 ArrayStack<Postorder_Pair, Node::MaxHeight> stack;
00385
00386 Postorder_Pair __pair;
00387
00388 Node *& p = __pair.first = root;
00389 char & side = __pair.second = 'i';
00390
00391 stack.push(__pair);
00392
00393 size_t count = 0;
00394
00395 while (not stack.is_empty())
00396 {
00397 __pair = stack.pop();
00398
00399 switch (side)
00400 {
00401 case 'i':
00402 if (LLINK(p) != Node::NullPtr)
00403 stack.push(Postorder_Pair(LLINK(p), 'i'));
00404
00405 stack.push(Postorder_Pair(p, 'l'));
00406
00407 break;
00408 case 'l':
00409 if (RLINK(p) != Node::NullPtr)
00410 stack.push(Postorder_Pair(RLINK(p), 'i'));
00411
00412 stack.push(Postorder_Pair(p, 'r'));
00413
00414 break;
00415 case 'r':
00416 (*visitFct) (p, stack.size(), count++);
00417
00418 break;
00419 }
00420 }
00421
00422 return count;
00423 }
00433 template <class Node> inline
00434 size_t compute_cardinality_rec(Node * node)
00435 {
00436 if (node == Node::NullPtr)
00437 return 0;
00438
00439 return (compute_cardinality_rec(LLINK(node)) + 1 +
00440 compute_cardinality_rec(RLINK(node)));
00441 }
00451 template <class Node> inline
00452 size_t computeHeightRec(Node * node)
00453 {
00454 if (node == Node::NullPtr)
00455 return 0;
00456
00457 const size_t left_height = computeHeightRec(LLINK(node));
00458 const size_t right_height = computeHeightRec(RLINK(node));
00459
00460 return 1 + Aleph::max(left_height, right_height);
00461 }
00472 template <class Node> inline
00473 Node * copyRec(Node * src_root) throw(std::exception, std::bad_alloc)
00474 {
00475 if (src_root == Node::NullPtr)
00476 return (Node*) Node::NullPtr;
00477
00478 Node * tgt_root = new Node(*src_root);
00479
00480 try
00481 {
00482 LLINK(tgt_root) = copyRec<Node>(static_cast<Node*>(LLINK(src_root)));
00483 RLINK(tgt_root) = copyRec<Node>(static_cast<Node*>(RLINK(src_root)));
00484 }
00485 catch (...)
00486 {
00487
00488 I(RLINK(tgt_root) == Node::NullPtr);
00489
00490 if (LLINK(tgt_root) != Node::NullPtr)
00491 destroyRec(LLINK(tgt_root));
00492
00493 delete tgt_root;
00494
00495 throw;
00496 }
00497
00498 return tgt_root;
00499 }
00508 template <class Node> inline
00509 void destroyRec(Node * root)
00510 {
00511 if (root == Node::NullPtr)
00512 return;
00513
00514 destroyRec(static_cast <Node*> (LLINK(root)));
00515 destroyRec(static_cast <Node*> (RLINK(root)));
00516
00517 delete root;
00518 }
00529 template <class Node> inline
00530 bool areSimilar(Node * t1, Node * t2)
00531 {
00532 if (t1 == Node::NullPtr and t2 == Node::NullPtr)
00533 return true;
00534
00535 if (t1 == Node::NullPtr or t2 == Node::NullPtr)
00536 return false;
00537
00538 return (areSimilar(LLINK(t1), LLINK(t2)) and
00539 areSimilar(RLINK(t1), RLINK(t2)));
00540 }
00559 template <class Node, class Equal> inline
00560 bool areEquivalents(Node * t1, Node * t2)
00561 {
00562 if (t1 == Node::NullPtr and t2 == Node::NullPtr)
00563 return true;
00564
00565 if (t1 == Node::NullPtr or t2 == Node::NullPtr)
00566 return false;
00567
00568 if (not Equal () (KEY(t1), KEY(t2)))
00569 return false;
00570
00571 return (areEquivalents<Node, Equal>(LLINK(t1), LLINK(t2)) and
00572 areEquivalents<Node, Equal>(RLINK(t1), RLINK(t2)));
00573 }
00574 template <class Node> inline
00575 bool areEquivalents(Node * t1, Node * t2)
00576 {
00577 return
00578 areEquivalents<Node, Aleph::equal_to<typename Node::key_type> >(t1, t2);
00579 }
00610 template <class Node> inline
00611 void levelOrder(Node * root,
00612 void (*visitFct)(Node*, int, bool),
00613 const size_t & queue_size)
00614 {
00615 if (root == Node::NullPtr)
00616 return;
00617
00618 const size_t two_power =
00619 static_cast<size_t>(std::log((float)queue_size)/std::log(2.0) + 1);
00620
00621 ArrayQueue<Aleph::pair<Node*, bool> > queue(two_power);
00622
00623 queue.put(root);
00624
00625 for (int pos = 0; not queue.is_empty(); pos++)
00626 {
00627 Aleph::pair<Node*, bool> pr = queue.get();
00628
00629 Node *& p = pr.first;
00630
00631 (*visitFct) (p, pos, pr.second);
00632
00633 if (LLINK(p) != Node::NullPtr)
00634 queue.put(Aleph::pair <Node*, bool> (LLINK(p), true));
00635
00636 if (RLINK(p) != Node::NullPtr)
00637 queue.put(Aleph::pair <Node*, bool> (RLINK(p), false));
00638 }
00639 }
00662 template <template <class> class Node, typename Key> inline
00663 Node<Key> * build_tree(DynArray<Key> & preorder,
00664 const int & l_p, const int & r_p,
00665 DynArray<Key> & inorder,
00666 const int & l_i, const int & r_i)
00667 {
00668 if (l_p > r_p)
00669
00670 {
00671 I(l_i > r_i);
00672
00673 return Node <Key> ::NullPtr;
00674
00675 }
00676
00677 I(r_p - l_p == r_i - l_i);
00678
00679
00680 Node<Key> * root = new Node <Key> (preorder[l_p]);
00681
00682 if (r_p == l_p)
00683 return root;
00684
00685
00686 I(l_i <= r_i);
00687
00688 int i = 0;
00689 for (int j = l_i; j <= r_i; ++j)
00690 if (inorder[j] == preorder[l_p])
00691 {
00692 i = j - l_i;
00693 break;
00694 }
00695
00696 I(i <= r_i);
00697
00698
00699 LLINK(root) = build_tree <Node, Key> (preorder, l_p + 1, l_p + i,
00700 inorder, l_i, l_i + (i - 1));
00701
00702 RLINK(root) = build_tree <Node, Key> (preorder, l_p + i + 1, r_p,
00703 inorder, l_i + i + 1, r_i);
00704
00705 return root;
00706 }
00707 template <class Node> inline static
00708 void __compute_nodes_in_level(Node * root,
00709 const int & level,
00710 const int & current_level,
00711 DynDlist<Node*> & level_list)
00712 {
00713 if (root == Node::NullPtr)
00714 return;
00715
00716 if (level == current_level)
00717 {
00718 level_list.append(root);
00719
00720 return;
00721 }
00722
00723 __compute_nodes_in_level(LLINK(root), level, current_level + 1, level_list);
00724
00725 __compute_nodes_in_level(RLINK(root), level, current_level + 1, level_list);
00726 }
00740 template <class Node> inline
00741 void compute_nodes_in_level(Node * root,
00742 const int & level,
00743 DynDlist<Node*>& list)
00744 {
00745 __compute_nodes_in_level(root, level, 0, list);
00746 }
00772 template <class Node> inline
00773 void inOrderThreaded(Node * root, void (*visitFct)(Node*))
00774 {
00775 if (root == Node::NullPtr)
00776 return;
00777
00778 Node *p = root, *r = Node::NullPtr, *q;
00779
00780 while (p != Node::NullPtr)
00781 {
00782 q = LLINK(p);
00783
00784 if (q == Node::NullPtr)
00785 {
00786
00787 (*visitFct)(p);
00788
00789 r = p;
00790 p = RLINK(p);
00791
00792 continue;
00793 }
00794
00795
00796 while (q != r and RLINK(q) != Node::NullPtr)
00797 q = RLINK(q);
00798
00799 if (q != r)
00800 {
00801 RLINK(q) = p;
00802 p = LLINK(p);
00803
00804 continue;
00805 }
00806
00807 (*visitFct)(p);
00808
00809 RLINK (q) = Node::NullPtr;
00810 r = p;
00811 p = RLINK(p);
00812 }
00813 }
00839 template <class Node> inline
00840 void preOrderThreaded(Node * node, void (*visitFct)(Node*))
00841 {
00842 if (node == Node::NullPtr)
00843 return;
00844
00845 Node *p = node, *r = Node::NullPtr, *q;
00846
00847 while (p != Node::NullPtr)
00848 {
00849 q = LLINK(p);
00850
00851 if (q == Node::NullPtr)
00852 {
00853 (*visitFct)(p);
00854
00855 r = p;
00856 p = RLINK(p);
00857
00858 continue;
00859 }
00860
00861
00862 while (q != r and RLINK(q) != Node::NullPtr)
00863 q = RLINK(q);
00864
00865 if (q != r)
00866 {
00867 RLINK(q) = p;
00868
00869 (*visitFct)(p);
00870
00871 p = LLINK(p);
00872
00873 continue;
00874 }
00875
00876 RLINK(q) = Node::NullPtr;
00877 r = p;
00878 p = RLINK(p);
00879 }
00880 }
00881 template <class Node> inline static
00882 size_t __internal_path_length(Node * p, const size_t & level)
00883 {
00884 if (p == Node::NullPtr)
00885 return 0;
00886
00887 return level + __internal_path_length(LLINK(p), level + 1) +
00888 __internal_path_length(RLINK(p), level + 1);
00889 }
00897 template <class Node> inline
00898 size_t internal_path_length(Node * p)
00899 {
00900 return __internal_path_length(p, 0);
00901 }
00914 template <class Node, class Compare> inline
00915 bool check_binary_search_tree(Node * node)
00916 {
00917 if (node == Node::NullPtr)
00918 return true;
00919
00920 if (LLINK(node) != Node::NullPtr)
00921 {
00922 if (Compare () (KEY(LLINK(node)), KEY(node)))
00923 return check_binary_search_tree<Node, Compare>(LLINK(node));
00924 else
00925 return false;
00926 }
00927
00928 if (RLINK(node) != Node::NullPtr)
00929 {
00930 if (Compare () (KEY(node), KEY(RLINK(node))))
00931 return check_binary_search_tree<Node, Compare>(RLINK(node));
00932 else
00933 return false;
00934 }
00935
00936 return true;
00937 }
00938
00939 template <class Node> inline
00940 bool check_binary_search_tree(Node * node)
00941 {
00942 return
00943 check_binary_search_tree<Node, Aleph::less<typename Node::key_type> >(node);
00944 }
00959 template <class Node> inline
00960 Node *
00961 preorder_to_binary_search_tree(DynArray<typename Node::key_type> & preorder,
00962 const int & l, const int & r)
00963 {
00964 if (l > r)
00965 return Node::NullPtr;
00966
00967 Node * root = new Node(preorder[l]);
00968
00969 if (l == r)
00970 return root;
00971
00972 int first_greater = l + 1;
00973
00974 while ( (first_greater <= r) and (preorder[first_greater] < preorder[l]))
00975 ++first_greater;
00976 LLINK(root) =
00977 preorder_to_binary_search_tree<Node>(preorder, l + 1, first_greater - 1);
00978 RLINK(root) =
00979 preorder_to_binary_search_tree<Node>(preorder, first_greater, r);
00980
00981 return root;
00982 }
01000 template <class Node, class Compare> inline
01001 Node * searchInBinTree(Node * root, const typename Node::key_type & key)
01002 {
01003 Node * p = root;
01004
01005 while (p != Node::NullPtr)
01006 if (Compare () (key, KEY(p)))
01007 p = static_cast<Node*>(LLINK(p));
01008 else if (Compare() (KEY(p), key))
01009 p = static_cast<Node*>(RLINK(p));
01010 else
01011 break;
01012
01013 return p;
01014 }
01015 template <class Node> inline
01016 Node * searchInBinTree(Node *root, const typename Node::key_type & key)
01017 {
01018 return
01019 searchInBinTree<Node, Aleph::less<typename Node::key_type> >(root, key);
01020 }
01032 template <class Node>
01033 Node * find_min(Node * root)
01034 {
01035 Node * ret_val = root;
01036 while (LLINK(ret_val) != Node::NullPtr)
01037 ret_val = static_cast<Node*>(LLINK(ret_val));
01038
01039 return ret_val;
01040 }
01041
01053 template <class Node>
01054 Node * find_max(Node * root)
01055 {
01056 Node * ret_val = root;
01057 while (RLINK(ret_val) != Node::NullPtr)
01058 ret_val = static_cast<Node*>(RLINK(ret_val));
01059
01060 return ret_val;
01061 }
01074 template <class Node> inline
01075 Node * find_successor(Node* p, Node *& pp)
01076 {
01077
01078 I(p != Node::NullPtr);
01079 I(RLINK(p) != Node::NullPtr);
01080
01081 pp = p;
01082 p = static_cast<Node*>(RLINK(p));
01083
01084 while (LLINK(p) != Node::NullPtr)
01085 {
01086 pp = p;
01087 p = static_cast<Node*>(LLINK(p));
01088 }
01089
01090 return p;
01091 }
01104 template <class Node> inline
01105 Node* find_predecessor(Node * p, Node *& pp)
01106 {
01107 I(p != Node::NullPtr);
01108 I(LLINK(pp) != Node::NullPtr);
01109
01110 pp = p;
01111 p = static_cast<Node*>(LLINK(p));
01112
01113 while (RLINK(p) != Node::NullPtr)
01114 {
01115 pp = p;
01116 p = static_cast<Node*>(RLINK(p));
01117 }
01118
01119 return p;
01120 }
01143 template <class Node, class Compare> inline
01144 Node * search_parent(Node * root,
01145 const typename Node::key_type & key,
01146 Node *& parent)
01147 {
01148
01149 I((LLINK(parent) == root) or (RLINK(parent) == root));
01150 I(root != Node::NullPtr);
01151
01152 Compare cmp;
01153 Node * p = root;
01154
01155 while (true)
01156 if (cmp(key, KEY(p)))
01157 {
01158 if (LLINK(p) == Node::NullPtr)
01159 return p;
01160
01161 parent = p;
01162 p = static_cast<Node*>(LLINK(p));
01163 }
01164 else if (cmp(KEY(p), key))
01165 {
01166 if (RLINK(p) == Node::NullPtr)
01167 return p;
01168
01169 parent = p;
01170 p = static_cast<Node*>(RLINK(p));
01171 }
01172 else
01173 return p;
01174 }
01175 template <class Node> inline
01176 Node * search_parent(Node * root, const typename Node::key_type & key,
01177 Node *& parent)
01178 {
01179 return search_parent<Node, Aleph::less<typename Node::key_type> >
01180 (root, key, parent);
01181 }
01199 template <class Node, class Compare> inline
01200 Node * search_rank_parent(Node * root, const typename Node::key_type & key)
01201 {
01202
01203 I(root != Node::NullPtr);
01204
01205 Compare cmp;
01206 Node *p = root;
01207
01208 while (true)
01209 if (cmp(key, KEY(p)))
01210 {
01211 if (LLINK(p) == Node::NullPtr)
01212 return p;
01213
01214 p = static_cast<Node*>(LLINK(p));
01215 }
01216 else if (cmp(KEY(p), key))
01217 {
01218 if (RLINK(p) == Node::NullPtr)
01219 return p;
01220
01221 p = static_cast<Node*>(RLINK(p));
01222 }
01223 else
01224 return p;
01225 }
01226 template <class Node> inline
01227 Node * search_rank_parent(Node * root, const typename Node::key_type & key)
01228 {
01229 return
01230 search_rank_parent<Node, Aleph::less<typename Node::key_type> >(root, key);
01231 }
01250 template <class Node, class Compare> inline
01251 Node * insert_in_binary_search_tree(Node *& root, Node * p)
01252 {
01253 if (root == Node::NullPtr)
01254 return root = p;
01255
01256 if (Compare () (KEY(p), KEY(root)))
01257
01258 return insert_in_binary_search_tree <Node, Compare>
01259 (static_cast<Node*&>(LLINK(root)), p);
01260 else if (Compare () (KEY(root), KEY(p)))
01261
01262 return insert_in_binary_search_tree <Node, Compare>
01263 (static_cast<Node*&>(RLINK(root)), p);
01264
01265 return Node::NullPtr;
01266 }
01267
01268 template <class Node> inline
01269 Node * insert_in_binary_search_tree(Node *& root, Node * p)
01270 {
01271 return
01272 insert_in_binary_search_tree<Node, Aleph::less<typename Node::key_type> >
01273 (root, p);
01274 }
01275 # define SPLIT split_key_rec<Node, Compare>
01276
01296 template <class Node, class Compare> inline
01297 bool split_key_rec(Node * root,
01298 const typename Node::key_type & key,
01299 Node *& ts, Node *& tg)
01300 {
01301 if (root == Node::NullPtr)
01302 {
01303 ts = tg = Node::NullPtr;
01304 return true;
01305 }
01306 if ( Compare() (key, KEY(root)) )
01307 {
01308 if (SPLIT(static_cast<Node*&>(LLINK(root)), key,
01309 ts, static_cast<Node*&>(LLINK(root))))
01310 {
01311 tg = root;
01312 return true;
01313 }
01314 else
01315 return false;
01316 }
01317 if ( Compare() (KEY(root), key) )
01318 {
01319 if (SPLIT(static_cast<Node*&>(RLINK(root)), key,
01320 static_cast<Node*&>(RLINK(root)), tg))
01321 {
01322 ts = root;
01323 return true;
01324 }
01325 else
01326 return false;
01327 }
01328 return false;
01329 }
01330
01331 # undef SPLIT
01332
01333 template <class Node> inline
01334 bool split_key_rec(Node * root, const typename Node::key_type & key,
01335 Node *& l, Node *& r)
01336 {
01337 return split_key_rec<Node, Aleph::less<typename Node::key_type> >(root,
01338 key, l, r);
01339 }
01355 template <class Node> inline
01356 Node * join_exclusive(Node *& ts, Node *& tg)
01357 {
01358 if (ts == Node::NullPtr)
01359 return tg;
01360
01361 if (tg == Node::NullPtr)
01362 return ts;
01363
01364 LLINK(tg) = join_exclusive(RLINK(ts), LLINK(tg));
01365
01366 RLINK(ts) = tg;
01367
01368 Node * ret_val = ts;
01369
01370 ts = tg = Node::NullPtr;
01371
01372 return ret_val;
01373 }
01374 # define REMOVE remove_from_search_binary_tree<Node, Compare>
01375
01393 template <class Node, class Compare> inline
01394 Node * remove_from_search_binary_tree(Node *& root,
01395 const typename Node::key_type & key)
01396 {
01397 if (root == Node::NullPtr)
01398 return Node::NullPtr;
01399
01400 if (Compare () (key, KEY(root)))
01401 return REMOVE(static_cast<Node*&>(LLINK(root)), key);
01402 else if (Compare () (KEY(root), key))
01403 return REMOVE(static_cast<Node*&>(RLINK(root)), key);
01404
01405 Node * ret_val = root;
01406
01407 root = join_exclusive(static_cast<Node*&>(LLINK(root)),
01408 static_cast<Node*&>(RLINK(root)));
01409
01410 ret_val->reset();
01411
01412 return ret_val;
01413 }
01414 # undef REMOVE
01415 # define REMOVE remove_from_search_binary_tree<Node,\
01416 Aleph::less<typename Node::key_type> >
01417
01418 template <class Node> inline
01419 Node * remove_from_search_binary_tree(Node *& root,
01420 const typename Node::key_type & key)
01421 {
01422 return REMOVE(root, key);
01423 }
01424
01425 # undef REMOVE
01426
01446 template <class Node, class Compare> inline
01447 Node * insert_root(Node *& root, Node * p)
01448 {
01449 Node * l = Node::NullPtr,
01450 * r = Node::NullPtr;
01451
01452 if (not split_key_rec<Node, Compare>(root, KEY(p), l, r))
01453 return Node::NullPtr;
01454
01455 LLINK(p) = l;
01456 RLINK(p) = r;
01457
01458 root = p;
01459
01460 return root;
01461 }
01462 template <class Node> inline
01463 Node * insert_root(Node *& root, Node * p)
01464 {
01465 return insert_root<Node, Aleph::less<typename Node::key_type> >(root, p);
01466 }
01485 template <class Node, class Compare> inline
01486 Node * join_preorder(Node * t1, Node * t2, Node *& dup)
01487 {
01488 if (t2 == Node::NullPtr)
01489 return t1;
01490
01491 Node * l = static_cast<Node*>(LLINK(t2));
01492 Node * r = static_cast<Node*>(RLINK(t2));
01493
01494 if (insert_in_binary_search_tree <Node, Compare> (t1, t2) == Node::NullPtr)
01495
01496 insert_in_binary_search_tree<Node, Compare>(dup, t2);
01497
01498 join_preorder(t1, l, dup);
01499 join_preorder(t1, r, dup);
01500
01501 return t1;
01502 }
01520 template <class Node, class Compare> inline
01521 Node * join(Node * t1, Node * t2, Node *& dup)
01522 {
01523 if (t1 == Node::NullPtr)
01524 return t2;
01525
01526 if (t2 == Node::NullPtr)
01527 return t1;
01528
01529 Node * l = static_cast<Node*>(LLINK(t1));
01530 Node * r = static_cast<Node*>(RLINK(t1));
01531
01532 t1->reset();
01533
01534 if (insert_root<Node, Compare>(t2, t1) == Node::NullPtr)
01535 insert_in_binary_search_tree<Node, Compare>(dup, t1);
01536
01537 LLINK(t2) = join<Node, Compare>(l, static_cast<Node*>(LLINK(t2)), dup);
01538 RLINK(t2) = join<Node, Compare>(r, static_cast<Node*>(RLINK(t2)), dup);
01539
01540 return t2;
01541 }
01542
01543 template <class Node> inline
01544 Node * join(Node * t1, Node * t2, Node *& dup)
01545 {
01546 return join<Node, Aleph::less<typename Node::key_type> >(t1, t2, dup);
01547 }
01548
01553 template <class Node> inline
01554 Node * rotate_to_right(Node * p)
01555 {
01556
01557 I(p != Node::NullPtr);
01558
01559 Node * q = static_cast<Node*>(LLINK(p));
01560 LLINK(p) = RLINK(q);
01561 RLINK(q) = p;
01562
01563 return q;
01564 }
01577 template <class Node> inline
01578 Node * rotate_to_right(Node * p, Node * pp)
01579 {
01580
01581 I(p != Node::NullPtr);
01582 I(pp != Node::NullPtr);
01583 I((static_cast<Node*>(LLINK(pp)) == p) or
01584 (static_cast<Node*>(RLINK(pp)) == p));
01585
01586 Node *q = static_cast<Node*>(LLINK(p));
01587
01588 LLINK(p) = RLINK(q);
01589 RLINK(q) = p;
01590
01591 if (static_cast<Node*>(LLINK(pp)) == p)
01592 LLINK(pp) = q;
01593 else
01594 RLINK(pp) = q;
01595
01596 return q;
01597 }
01602 template <class Node> inline
01603 Node* rotate_to_left(Node * p)
01604 {
01605 I(p != Node::NullPtr);
01606
01607 Node *q = static_cast<Node*>(RLINK(p));
01608 RLINK(p) = LLINK(q);
01609 LLINK(q) = p;
01610
01611 return q;
01612 }
01613
01628 template <class Node> inline
01629 Node* rotate_to_left(Node * p, Node * pp)
01630 {
01631 I(p != Node::NullPtr);
01632 I(pp != Node::NullPtr);
01633 I(static_cast<Node*>(LLINK(pp)) == p or
01634 static_cast<Node*>(RLINK(pp)) == p);
01635
01636 Node *q = static_cast<Node*>(RLINK(p));
01637
01638 RLINK(p) = LLINK(q);
01639 LLINK(q) = p;
01640
01641
01642 if (LLINK(pp) == p)
01643 LLINK(pp) = q;
01644 else
01645 RLINK(pp) = q;
01646
01647 return q;
01648 }
01673 template <class Node, class Key, class Compare> inline
01674 void split_key(Node * root, const Key & key, Node *& l, Node *& r)
01675 {
01676 if (root == Node::NullPtr)
01677 {
01678 l = r = (Node*) Node::NullPtr;
01679 return;
01680 }
01681
01682 Node * current;
01683 Node ** current_parent = NULL;
01684 Node ** pending_child = NULL;
01685 char current_is_right;
01686 Compare cmp;
01687
01688 if (cmp (key, KEY(root)))
01689 {
01690 r = root;
01691 pending_child = &l;
01692 current_is_right = true;
01693 }
01694 else
01695 {
01696 l = root;
01697 pending_child = &r;
01698 current_is_right = false;
01699 }
01700 current = root;
01701
01702 while (current != Node::NullPtr)
01703 {
01704 if (cmp (key, KEY(current)))
01705 {
01706 if (not current_is_right)
01707 {
01708 current_is_right = not current_is_right;
01709 *pending_child = *current_parent;
01710 pending_child = current_parent;
01711 }
01712 current_parent = static_cast<Node**>(&LLINK(current));
01713 }
01714 else
01715 {
01716 if (current_is_right)
01717 {
01718 current_is_right = not current_is_right;
01719 *pending_child = *current_parent;
01720 pending_child = current_parent;
01721 }
01722 current_parent = static_cast<Node**>(&RLINK(current));
01723 }
01724 current = *current_parent;
01725 }
01726 *pending_child = static_cast<Node*>(Node::NullPtr);
01727 }
01728
01729 template <class Node, class Key> inline
01730 void split_key(Node *root, const Key& key, Node *& l, Node *& r)
01731 {
01732 split_key<Node, Key, Aleph::less<Key> >(root, key, l, r);
01733 }
01734
01752 template <class Node> inline
01753 void swap_node_with_successor(Node * p,
01754 Node *& pp,
01755 Node * q,
01756 Node *& pq)
01757
01758 {
01759 I(p != Node::NullPtr and q != Node::NullPtr and
01760 pp != Node::NullPtr and pq != Node::NullPtr);
01761 I(LLINK(pp) == p or RLINK(pp) == p);
01762 I(LLINK(pq) == q or RLINK(pq) == q);
01763 I(LLINK(q) == Node::NullPtr);
01764
01765
01766 if (LLINK(pp) == p)
01767 LLINK(pp) = q;
01768 else
01769 RLINK(pp) = q;
01770
01771 LLINK(q) = LLINK(p);
01772 LLINK(p) = Node::NullPtr;
01773
01774
01775
01776
01777 if (RLINK(p) == q)
01778 {
01779 RLINK(p) = RLINK(q);
01780 RLINK(q) = p;
01781 pq = pp;
01782 pp = q;
01783 return;
01784 }
01785
01786
01787
01788 Node *qr = RLINK(q);
01789 RLINK(q) = RLINK(p);
01790 LLINK(pq) = p;
01791 RLINK(p) = qr;
01792
01793 Aleph::swap(pp, pq);
01794 }
01795
01813 template <class Node> inline
01814 void swap_node_with_predecessor(Node * p,
01815 Node *& pp,
01816 Node * q,
01817 Node *& pq)
01818 {
01819 I((p != Node::NullPtr) and (q != Node::NullPtr) and
01820 (pp != Node::NullPtr) and (pq != Node::NullPtr));
01821 I((RLINK(pp) == p) or (LLINK(pp) == p));
01822 I((RLINK(pq) == q) or (LLINK(pq) == q));
01823 I(RLINK(q) == Node::NullPtr);
01824
01825
01826 if (RLINK(pp) == p)
01827 RLINK(pp) = q;
01828 else
01829 LLINK(pp) = q;
01830
01831 RLINK(q) = RLINK(p);
01832 RLINK(p) = Node::NullPtr;
01833
01834
01835
01836
01837 if (LLINK(p) == q)
01838 {
01839 LLINK(p) = LLINK(q);
01840 LLINK(q) = p;
01841 pq = pp;
01842 pp = q;
01843 return;
01844 }
01845
01846
01847
01848 Node *ql = LLINK(q);
01849 LLINK(q) = LLINK(p);
01850 RLINK(pq) = p;
01851 LLINK(p) = ql;
01852
01853 Aleph::swap(pp, pq);
01854 }
01855
01874 template <class Node, class Key, class Compare> inline
01875 Node * insert_root_rec(Node * root, Node * p)
01876 {
01877 if (root == Node::NullPtr)
01878 return p;
01879
01880 if (Compare () (KEY(p), KEY(root)))
01881 {
01882 Node *left_branch =
01883 insert_root_rec<Node, Key, Compare>(static_cast<Node*>(LLINK(root)),
01884 p);
01885 if (left_branch == Node::NullPtr)
01886 return (Node*) Node::NullPtr;
01887
01888 LLINK(root) = left_branch;
01889 root = rotate_to_right(root);
01890 }
01891 else if (Compare () (KEY(root), KEY(p) ))
01892 {
01893 Node *right_branch =
01894 insert_root_rec<Node, Key, Compare>(static_cast<Node*>(RLINK(root)),
01895 p);
01896 if (right_branch == Node::NullPtr)
01897 return (Node*) Node::NullPtr;
01898
01899 RLINK(root) = right_branch;
01900 root = rotate_to_left(root);
01901 }
01902 else
01903 return (Node*) Node::NullPtr;
01904
01905 return root;
01906 }
01907
01908 template <class Node, class Key> inline
01909 Node * insert_root_rec(Node * root, Node * p)
01910 {
01911 return insert_root_rec<Node, Key, Aleph::less<Key> >(root, p);
01912 }
01913
01914
01915 }
01916
01917 # endif // TPL_BINNODEUTILS_H
01918