BWAPI
|
00001 // Copyright (c) 2005 Tel-Aviv University (Israel). All rights reserved. 00002 // 00003 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00004 // modify it under the terms of the GNU Lesser General Public License as 00005 // published by the Free Software Foundation; version 2.1 of the License. 00006 // See the file LICENSE.LGPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/STL_Extension/include/CGAL/Multiset.h $ 00015 // $Id: Multiset.h 41420 2008-01-03 15:04:30Z spion $ 00016 // 00017 // 00018 // Author(s) : Ron Wein <wein@post.tau.ac.il> 00019 00020 #ifndef CGAL_MULTISET_H 00021 #define CGAL_MULTISET_H 00022 00023 #include <CGAL/config.h> 00024 #include <CGAL/assertions.h> 00025 #include <CGAL/multiset_assertions.h> 00026 #include <CGAL/enum.h> 00027 #include <CGAL/memory.h> 00028 #include <iterator> 00029 00030 CGAL_BEGIN_NAMESPACE 00031 00058 template <typename Type_, 00059 class Compare_ = CGAL::Compare<Type_>, 00060 class Allocator_ = CGAL_ALLOCATOR(int)> 00061 class Multiset 00062 { 00063 public: 00064 00065 // General type definitions: 00066 typedef Type_ Type; 00067 typedef Compare_ Compare; 00068 typedef Allocator_ Allocator; 00069 typedef Multiset<Type, Compare, Allocator> Self; 00070 00071 // Type definitions for STL compatibility. 00072 typedef Type value_type; 00073 typedef Type key_type; 00074 typedef value_type& reference; 00075 typedef const value_type& const_reference; 00076 typedef Compare key_compare; 00077 typedef Compare value_compare; 00078 typedef size_t size_type; 00079 typedef std::ptrdiff_t difference_type; 00080 00081 protected: 00082 00086 struct Node 00087 { 00088 00089 enum Color 00090 { 00091 RED, // Regular red node in the tree. 00092 BLACK, // Regular black node in the tree. 00093 DUMMY_BEGIN, // The dummy before-the-begin tree node. 00094 DUMMY_END // The dummy past-the-end tree node. 00095 }; 00096 00097 typedef char Node_color; 00098 00099 Type object; // The stored object. 00100 Node_color color; // The color of the node. 00101 Node *parentP; // Points on the parent node. 00102 Node *rightP; // Points on the right child of the node. 00103 Node *leftP; // Points on the left child of the node. 00104 00106 Node() : 00107 parentP(NULL), 00108 rightP(NULL), 00109 leftP(NULL) 00110 {} 00111 00117 Node (const Type& _object, Node_color _color) : 00118 object(_object), 00119 color(_color), 00120 parentP(NULL), 00121 rightP(NULL), 00122 leftP(NULL) 00123 {} 00124 00130 void init (const Type& _object, Node_color _color) 00131 { 00132 object = _object; 00133 color = _color; 00134 } 00135 00137 ~Node () 00138 {} 00139 00143 inline bool is_valid () const 00144 { 00145 return (color == BLACK || color == RED); 00146 } 00147 00151 inline bool is_red () const 00152 { 00153 return (color == RED); 00154 } 00155 00160 inline bool is_black () const 00161 { 00162 return (color != RED); 00163 } 00164 00168 Node* predecessor () const 00169 { 00170 // The DUMMY_BEGIN node has no predecessor. 00171 CGAL_multiset_assertion (color != DUMMY_BEGIN); 00172 00173 Node *predP; 00174 00175 if (leftP != NULL) 00176 { 00177 // If there is a left child, the predecessor is the maximal object in 00178 // the sub-tree spanned by this child. 00179 predP = leftP; 00180 while (predP->rightP != NULL) 00181 predP = predP->rightP; 00182 } 00183 else 00184 { 00185 // Otherwise, go up the tree until reaching the parent from the right 00186 // direction (this also covers the case of the DUMMY_END node). 00187 const Node *prevP = this; 00188 00189 predP = parentP; 00190 while (predP != NULL && prevP == predP->leftP) 00191 { 00192 prevP = predP; 00193 predP = predP->parentP; 00194 } 00195 } 00196 00197 return (predP); 00198 } 00199 00203 Node* successor () const 00204 { 00205 // The DUMMY_END node has no successor. 00206 CGAL_multiset_assertion (color != DUMMY_END); 00207 00208 Node *succP; 00209 00210 if (rightP != NULL) 00211 { 00212 // If there is a right child, the successor is the minimal object in 00213 // the sub-tree spanned by this child. 00214 succP = rightP; 00215 while (succP->leftP != NULL) 00216 succP = succP->leftP; 00217 } 00218 else 00219 { 00220 // Otherwise, go up the tree until reaching the parent from the left 00221 // direction (this also covers the case of the DUMMY_BEGIN node). 00222 const Node *prevP = this; 00223 00224 succP = parentP; 00225 while (succP != NULL && prevP == succP->rightP) 00226 { 00227 prevP = succP; 00228 succP = succP->parentP; 00229 } 00230 } 00231 00232 return (succP); 00233 } 00234 }; 00235 00236 // Rebind the allocator to the Node type: 00237 typedef typename Allocator::template rebind <Node> Node_alloc_rebind; 00238 typedef typename Node_alloc_rebind::other Node_allocator; 00239 00240 public: 00241 00242 // Forward decleration: 00243 class const_iterator; 00244 00249 class iterator 00250 { 00251 // Give the red-black tree class template access to the iterator's members. 00252 friend class Multiset<Type, Compare, Allocator>; 00253 friend class const_iterator; 00254 00255 public: 00256 00257 // Type definitions: 00258 typedef std::bidirectional_iterator_tag iterator_category; 00259 typedef Type value_type; 00260 typedef std::ptrdiff_t difference_type; 00261 typedef size_t size_type; 00262 typedef value_type& reference; 00263 typedef value_type* pointer; 00264 00265 private: 00266 00267 Node *nodeP; // Points to a tree node. 00268 00270 iterator (Node *_nodeP) : 00271 nodeP (_nodeP) 00272 {} 00273 00274 public: 00275 00277 iterator () : 00278 nodeP (NULL) 00279 {} 00280 00282 bool operator== (const iterator& iter) const 00283 { 00284 return (nodeP == iter.nodeP); 00285 } 00286 00288 bool operator!= (const iterator& iter) const 00289 { 00290 return (nodeP != iter.nodeP); 00291 } 00292 00294 iterator& operator++ () 00295 { 00296 CGAL_multiset_precondition (nodeP != NULL); 00297 00298 nodeP = nodeP->successor(); 00299 return (*this); 00300 } 00301 00303 iterator operator++ (int ) 00304 { 00305 CGAL_multiset_precondition (nodeP != NULL); 00306 00307 iterator temp = *this; 00308 00309 nodeP = nodeP->successor(); 00310 return (temp); 00311 } 00312 00314 iterator& operator-- () 00315 { 00316 CGAL_multiset_precondition (nodeP != NULL); 00317 00318 nodeP = nodeP->predecessor(); 00319 return (*this); 00320 } 00321 00323 iterator operator-- (int ) 00324 { 00325 CGAL_multiset_precondition (nodeP != NULL); 00326 00327 iterator temp = *this; 00328 00329 nodeP = nodeP->predecessor(); 00330 return (temp); 00331 } 00332 00336 reference operator* () const 00337 { 00338 CGAL_multiset_precondition (nodeP != NULL && nodeP->is_valid()); 00339 00340 return (nodeP->object); 00341 } 00342 00346 pointer operator-> () const 00347 { 00348 CGAL_multiset_precondition (nodeP != NULL && nodeP->is_valid()); 00349 00350 return (&(nodeP->object)); 00351 } 00352 00353 }; 00354 friend class iterator; 00355 00360 class const_iterator 00361 { 00362 // Give the red-black tree class template access to the iterator's members. 00363 friend class Multiset<Type, Compare, Allocator>; 00364 00365 public: 00366 00367 // Type definitions: 00368 typedef std::bidirectional_iterator_tag iterator_category; 00369 typedef Type value_type; 00370 typedef std::ptrdiff_t difference_type; 00371 typedef size_t size_type; 00372 typedef const value_type& reference; 00373 typedef const value_type* pointer; 00374 00375 private: 00376 00377 const Node *nodeP; // Points to a tree node. 00378 00380 const_iterator (const Node *_nodeP) : 00381 nodeP (_nodeP) 00382 {} 00383 00384 public: 00385 00387 const_iterator () : 00388 nodeP (NULL) 00389 {} 00390 00392 const_iterator (const iterator& iter) : 00393 nodeP (iter.nodeP) 00394 {} 00395 00397 bool operator== (const const_iterator& iter) const 00398 { 00399 return (nodeP == iter.nodeP); 00400 } 00401 00403 bool operator!= (const const_iterator& iter) const 00404 { 00405 return (nodeP != iter.nodeP); 00406 } 00407 00409 const_iterator& operator++ () 00410 { 00411 CGAL_multiset_precondition (nodeP != NULL); 00412 00413 nodeP = nodeP->successor(); 00414 return (*this); 00415 } 00416 00418 const_iterator operator++ (int ) 00419 { 00420 CGAL_multiset_precondition (nodeP != NULL); 00421 00422 const_iterator temp = *this; 00423 00424 nodeP = nodeP->successor(); 00425 return (temp); 00426 } 00427 00429 const_iterator& operator-- () 00430 { 00431 CGAL_multiset_precondition (nodeP != NULL); 00432 00433 nodeP = nodeP->predecessor(); 00434 return (*this); 00435 } 00436 00438 const_iterator operator-- (int ) 00439 { 00440 CGAL_multiset_precondition (nodeP != NULL); 00441 00442 const_iterator temp = *this; 00443 00444 nodeP = nodeP->predecessor(); 00445 return (temp); 00446 } 00447 00451 reference operator* () const 00452 { 00453 CGAL_multiset_precondition (nodeP != NULL && nodeP->is_valid()); 00454 00455 return (nodeP->object); 00456 } 00457 00461 pointer operator-> () const 00462 { 00463 CGAL_multiset_precondition (nodeP != NULL && nodeP->is_valid()); 00464 00465 return (&(nodeP->object)); 00466 } 00467 00468 }; 00469 friend class const_iterator; 00470 00471 // Define the reverse iterators: 00472 typedef std::reverse_iterator<iterator> reverse_iterator; 00473 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00474 00475 protected: 00476 00477 // Data members: 00478 Node *rootP; // Pointer to the tree root. 00479 size_t iSize; // Number of objects stored in the tree. 00480 size_t iBlackHeight; // The black-height of the tree (the number 00481 // of black nodes from the root to each leaf). 00482 Compare comp_f; // A comparison functor. 00483 Node_allocator node_alloc; // Allocator for the tree nodes. 00484 Node beginNode; // A fictitious before-the-minimum node. 00485 // Its parent is the leftmost tree node. 00486 Node endNode; // A fictitious past-the-maximum node. 00487 // Its parent is the rightmost tree node. 00488 00489 public: 00490 00492 00493 00497 Multiset (); 00498 00503 Multiset (const Compare& comp); 00504 00509 Multiset (const Self& tree); 00510 00517 template <class InputIterator> 00518 Multiset (InputIterator first, InputIterator last, 00519 const Compare& comp = Compare()) : 00520 rootP (NULL), 00521 iSize (0), 00522 iBlackHeight (0), 00523 comp_f (comp) 00524 { 00525 // Mark the two fictitious nodes as dummies. 00526 beginNode.color = Node::DUMMY_BEGIN; 00527 endNode.color = Node::DUMMY_END; 00528 00529 // Insert all objects to the tree. 00530 while (first != last) 00531 { 00532 insert (*first); 00533 ++first; 00534 } 00535 } 00536 00540 virtual ~Multiset (); 00541 00546 Self& operator= (const Self& tree); 00547 00552 void swap (Self& tree); 00554 00556 00557 00562 bool operator== (const Self& tree) const; 00563 00568 bool operator< (const Self& tree) const; 00570 00572 00573 00577 inline Compare& key_comp () 00578 { 00579 return (comp_f); 00580 } 00581 00585 inline Compare& value_comp () 00586 { 00587 return (comp_f); 00588 } 00589 00590 00594 inline const Compare& key_comp () const 00595 { 00596 return (comp_f); 00597 } 00598 00602 inline const Compare& value_comp () const 00603 { 00604 return (comp_f); 00605 } 00606 00610 inline iterator begin (); 00611 00615 inline iterator end (); 00616 00620 inline const_iterator begin () const; 00621 00625 inline const_iterator end () const; 00626 00631 inline reverse_iterator rbegin (); 00632 00637 inline reverse_iterator rend (); 00638 00642 inline const_reverse_iterator rbegin () const; 00643 00647 inline const_reverse_iterator rend () const; 00648 00652 inline bool empty () const 00653 { 00654 return (rootP == NULL); 00655 } 00656 00662 size_t size () const; 00663 00667 size_t max_size () const 00668 { 00669 return (size()); 00670 } 00672 00674 00680 iterator insert (const Type& object); 00681 00687 template <class InputIterator> 00688 void insert (InputIterator first, InputIterator last) 00689 { 00690 // Insert all objects to the tree. 00691 while (first != last) 00692 { 00693 insert (*first); 00694 ++first; 00695 } 00696 00697 return; 00698 } 00699 00707 iterator insert (iterator position, 00708 const Type& object); 00709 00720 iterator insert_after (iterator position, 00721 const Type& object); 00722 00733 iterator insert_before (iterator position, 00734 const Type& object); 00736 00738 00739 00746 size_t erase (const Type& object); 00747 00755 void erase (iterator position); 00756 00760 void clear (); 00761 00763 00765 00766 00775 iterator find (const Type& object) 00776 { 00777 return (find (object, comp_f)); 00778 } 00779 00780 template <class Key, class CompareKey> 00781 iterator find (const Key& key, 00782 const CompareKey& comp_key) 00783 { 00784 bool is_equal; 00785 Node *nodeP = _bound (LOWER_BOUND, key, comp_key, is_equal); 00786 00787 if (_is_valid(nodeP) && is_equal) 00788 return (iterator (nodeP)); 00789 else 00790 return (iterator (&endNode)); 00791 } 00792 00801 const_iterator find (const Type& object) const 00802 { 00803 return (find (object, comp_f)); 00804 } 00805 00806 template <class Key, class CompareKey> 00807 const_iterator find (const Key& key, 00808 const CompareKey& comp_key) const 00809 { 00810 bool is_equal; 00811 const Node *nodeP = _bound (LOWER_BOUND, key, comp_key, is_equal); 00812 00813 if (_is_valid (nodeP) && is_equal) 00814 return (const_iterator (nodeP)); 00815 else 00816 return (const_iterator (&endNode)); 00817 } 00818 00826 size_type count (const Type& object) const 00827 { 00828 return (count (object, comp_f)); 00829 } 00830 00831 template <class Key, class CompareKey> 00832 size_type count (const Key& key, 00833 const CompareKey& comp_key) const 00834 { 00835 // Get the first equivalent object (if any). 00836 size_t n_objects = 0; 00837 bool is_equal; 00838 const Node *nodeP = _bound (LOWER_BOUND, key, comp_key, is_equal); 00839 00840 if (! is_equal) 00841 return (0); 00842 00843 while (_is_valid (nodeP) && 00844 comp_key (key, nodeP->object) == EQUAL) 00845 { 00846 n_objects++; 00847 00848 // Proceed to the successor. 00849 nodeP = nodeP->successor(); 00850 } 00851 00852 return (n_objects); 00853 } 00854 00863 iterator lower_bound (const Type& object) 00864 { 00865 return (lower_bound (object, comp_f)); 00866 } 00867 00868 template <class Key, class CompareKey> 00869 iterator lower_bound (const Key& key, 00870 const CompareKey& comp_key) 00871 { 00872 bool is_equal; 00873 Node *nodeP = _bound (LOWER_BOUND, key, comp_key, is_equal); 00874 00875 if (_is_valid (nodeP)) 00876 return (iterator (nodeP)); 00877 else 00878 return (iterator (&endNode)); 00879 } 00880 00889 std::pair<iterator, bool> find_lower (const Type& object) 00890 { 00891 return (find_lower (object, comp_f)); 00892 } 00893 00894 template <class Key, class CompareKey> 00895 std::pair<iterator, bool> find_lower (const Key& key, 00896 const CompareKey& comp_key) 00897 { 00898 bool is_equal; 00899 Node *nodeP = _bound (LOWER_BOUND, key, comp_key, is_equal); 00900 00901 if (_is_valid (nodeP)) 00902 return (std::make_pair (iterator (nodeP), is_equal)); 00903 else 00904 return (std::make_pair (iterator (&endNode), false)); 00905 } 00906 00915 iterator upper_bound (const Type& object) 00916 { 00917 return (upper_bound (object, comp_f)); 00918 } 00919 00920 template <class Key, class CompareKey> 00921 iterator upper_bound (const Key& key, 00922 const CompareKey& comp_key) 00923 { 00924 bool is_equal; 00925 Node *nodeP = _bound (UPPER_BOUND, key, comp_key, is_equal); 00926 00927 if (_is_valid (nodeP)) 00928 return (iterator (nodeP)); 00929 else 00930 return (iterator (&endNode)); 00931 } 00932 00941 const_iterator lower_bound (const Type& object) const 00942 { 00943 return (lower_bound (object, comp_f)); 00944 } 00945 00946 template <class Key, class CompareKey> 00947 const_iterator lower_bound (const Key& key, 00948 const CompareKey& comp_key) const 00949 { 00950 bool is_equal; 00951 const Node *nodeP = _bound (LOWER_BOUND, key, comp_key, is_equal); 00952 00953 if (_is_valid (nodeP)) 00954 return (const_iterator (nodeP)); 00955 else 00956 return (const_iterator (&endNode)); 00957 } 00958 00967 std::pair<const_iterator, bool> find_lower (const Type& object) const 00968 { 00969 return (find_lower (object, comp_f)); 00970 } 00971 00972 template <class Key, class CompareKey> 00973 std::pair<const_iterator, bool> find_lower (const Key& key, 00974 const CompareKey& comp_key) const 00975 { 00976 bool is_equal; 00977 const Node *nodeP = _bound (LOWER_BOUND, key, comp_key, is_equal); 00978 00979 if (_is_valid (nodeP)) 00980 return (std::make_pair (const_iterator (nodeP), is_equal)); 00981 else 00982 return (std::make_pair (const_iterator (&endNode), false)); 00983 } 00984 00992 const_iterator upper_bound (const Type& object) const 00993 { 00994 return (upper_bound (object, comp_f)); 00995 } 00996 00997 template <class Key, class CompareKey> 00998 const_iterator upper_bound (const Key& key, 00999 const CompareKey& comp_key) const 01000 { 01001 bool is_equal; 01002 const Node *nodeP = _bound (UPPER_BOUND, key, comp_key, is_equal); 01003 01004 if (_is_valid (nodeP)) 01005 return (const_iterator (nodeP)); 01006 else 01007 return (const_iterator (&endNode)); 01008 } 01009 01017 std::pair<iterator, iterator> equal_range (const Type& object) 01018 { 01019 return (equal_range (object, comp_f)); 01020 } 01021 01022 template <class Key, class CompareKey> 01023 std::pair<iterator, iterator> 01024 equal_range (const Key& key, 01025 const CompareKey& comp_key) 01026 { 01027 // Get the first equivalent object (if any). 01028 const size_t max_steps = static_cast<size_t> (1.5 * iBlackHeight); 01029 bool is_equal; 01030 Node *lowerP = _bound (LOWER_BOUND, key, comp_key, is_equal); 01031 Node *upperP = lowerP; 01032 size_t n_objects = 0; 01033 01034 if (is_equal) 01035 { 01036 while (_is_valid (upperP) && 01037 comp_key (key, upperP->object) == EQUAL) 01038 { 01039 n_objects++; 01040 if (n_objects >= max_steps) 01041 { 01042 // If we have more than log(n) objects in the range, locate the 01043 // upper bound directly. 01044 upperP = _bound (UPPER_BOUND, key, comp_key, is_equal); 01045 break; 01046 } 01047 01048 // Proceed to the successor. 01049 upperP = upperP->successor(); 01050 } 01051 } 01052 01053 return (std::pair<iterator, iterator> 01054 ((_is_valid (lowerP)) ? iterator (lowerP) : iterator (&endNode), 01055 (_is_valid (upperP)) ? iterator (upperP) : iterator (&endNode))); 01056 } 01057 01065 std::pair<const_iterator, const_iterator> 01066 equal_range (const Type& object) const 01067 { 01068 return (equal_range (object, comp_f)); 01069 } 01070 01071 template <class Key, class CompareKey> 01072 std::pair<const_iterator, const_iterator> 01073 equal_range (const Key& key, 01074 const CompareKey& comp_key) const 01075 { 01076 // Get the first equivalent object (if any). 01077 const size_t max_steps = static_cast<size_t> (1.5 * iBlackHeight); 01078 bool is_equal; 01079 const Node *lowerP = _bound (LOWER_BOUND, key, comp_key, is_equal); 01080 const Node *upperP = lowerP; 01081 size_t n_objects = 0; 01082 01083 if (is_equal) 01084 { 01085 while (_is_valid (upperP) && 01086 comp_key (key, upperP->object) == EQUAL) 01087 { 01088 n_objects++; 01089 if (n_objects >= max_steps) 01090 { 01091 // If we have more than log(n) objects in the range, locate the 01092 // upper bound directly. 01093 upperP = _bound (UPPER_BOUND, key, comp_key, is_equal); 01094 break; 01095 } 01096 01097 // Proceed to the successor. 01098 upperP = upperP->successor(); 01099 } 01100 } 01101 01102 return (std::pair<const_iterator, const_iterator> 01103 ((_is_valid (lowerP)) ? const_iterator(lowerP) : 01104 const_iterator(&endNode), 01105 (_is_valid (upperP)) ? const_iterator(upperP) : 01106 const_iterator(&endNode))); 01107 } 01109 01111 01112 01121 void replace (iterator position, 01122 const Type& object); 01123 01132 void swap (iterator pos1, iterator pos2); 01133 01143 void catenate (Self& tree); 01144 01155 void split (const Type& object, Self& tree) 01156 { 01157 split (object, comp_f, tree); 01158 return; 01159 } 01160 01161 template <class Key, class CompareKey> 01162 void split (const Key& key, const CompareKey& comp_key, 01163 Self& tree) 01164 { 01165 split (lower_bound (key, comp_key), tree); 01166 return; 01167 } 01168 01177 void split (iterator position, Self& tree); 01178 01180 01182 01183 01189 bool is_valid() const; 01190 01195 size_t height () const; 01196 01201 inline size_t black_height () const 01202 { 01203 return (iBlackHeight); 01204 } 01206 01207 protected: 01208 01210 01211 01213 inline bool _is_valid (const Node *nodeP) const 01214 { 01215 return (nodeP != NULL && nodeP->is_valid()); 01216 } 01217 01219 inline bool _is_red (const Node *nodeP) const 01220 { 01221 return (nodeP != NULL && nodeP->color == Node::RED); 01222 } 01223 01225 inline bool _is_black (const Node *nodeP) const 01226 { 01227 // Note that invalid nodes are considered ro be black as well. 01228 return (nodeP == NULL || nodeP->color != Node::RED); 01229 } 01231 01233 01234 01240 void _shallow_assign (Self& tree); 01241 01246 void _shallow_clear (); 01247 01262 enum Bound_type {LOWER_BOUND, UPPER_BOUND}; 01263 01264 template <class Key, class CompareKey> 01265 Node* _bound (Bound_type type, 01266 const Key& key, 01267 const CompareKey& comp_key, 01268 bool& is_equal) const 01269 { 01270 // Initially mark that the key is not found in the tree. 01271 is_equal = false; 01272 01273 if (rootP == NULL) 01274 // The tree is empty: 01275 return (NULL); 01276 01277 Node *currentP = rootP; 01278 Node *prevP = currentP; 01279 Comparison_result comp_res = EQUAL; 01280 01281 while (_is_valid (currentP)) 01282 { 01283 comp_res = comp_key (key, currentP->object); 01284 01285 if (comp_res == EQUAL) 01286 { 01287 // The key is found in the tree: 01288 if (type == LOWER_BOUND) 01289 { 01290 is_equal = true; 01291 01292 // Lower bound computation: 01293 // Go backward as long as we find equivalent objects. 01294 prevP = currentP->predecessor(); 01295 while (_is_valid (prevP)) 01296 { 01297 if (comp_key (key, prevP->object) != EQUAL) 01298 break; 01299 currentP = prevP; 01300 prevP = currentP->predecessor(); 01301 } 01302 } 01303 else 01304 { 01305 // Upper bound computation: 01306 // Go backward until we encounter a non-equivalent objects. 01307 do 01308 { 01309 currentP = currentP->successor(); 01310 } while (_is_valid (currentP) && 01311 comp_key (key, currentP->object) == EQUAL); 01312 } 01313 01314 return (currentP); 01315 } 01316 else if (comp_res == SMALLER) 01317 { 01318 prevP = currentP; 01319 01320 // Go down to the left child. 01321 currentP = currentP->leftP; 01322 } 01323 else // comp_res == LARGER 01324 { 01325 prevP = currentP; 01326 01327 // Go down to the right child. 01328 currentP = currentP->rightP; 01329 } 01330 } 01331 01332 // If we reached here, the object is not found in the tree. We check if the 01333 // last node we visited (given by prevP) contains an object greater than 01334 // the query object. If not, we return its successor. 01335 if (comp_res == SMALLER) 01336 return (prevP); 01337 else 01338 return (prevP->successor()); 01339 } 01340 01345 void _remove_at (Node* nodeP); 01346 01352 void _swap (Node* node1_P, Node* node2_P); 01353 01360 void _swap_siblings (Node* node1_P, Node* node2_P); 01361 01367 size_t _sub_height (const Node* nodeP) const; 01368 01375 bool _sub_is_valid (const Node* nodeP, 01376 size_t& sub_size, 01377 size_t& sub_bh) const; 01378 01384 Node* _sub_minimum (Node* nodeP) const; 01385 01391 Node* _sub_maximum (Node* nodeP) const; 01392 01397 void _rotate_left (Node* nodeP); 01398 01403 void _rotate_right (Node* nodeP); 01404 01410 Node* _duplicate (const Node* nodeP); 01411 01416 void _destroy (Node* nodeP); 01417 01422 void _insert_fixup (Node* nodeP); 01423 01431 void _remove_fixup (Node* nodeP, Node* parentP); 01432 01439 Node* _allocate_node (const Type& object, 01440 typename Node::Node_color color) 01441 #ifdef CGAL_CFG_OUTOFLINE_MEMBER_DEFINITION_BUG 01442 { 01443 CGAL_multiset_assertion (color != Node::DUMMY_BEGIN && 01444 color != Node::DUMMY_END); 01445 01446 Node* new_node = node_alloc.allocate(1); 01447 01448 node_alloc.construct(new_node, beginNode); 01449 new_node->init(object, color); 01450 return (new_node); 01451 } 01452 #else 01453 ; 01454 #endif 01455 01460 void _deallocate_node (Node* nodeP); 01462 }; 01463 01464 //--------------------------------------------------------- 01465 // Default constructor. 01466 // 01467 template <class Type, class Compare, typename Allocator> 01468 Multiset<Type, Compare, Allocator>::Multiset () : 01469 rootP (NULL), 01470 iSize (0), 01471 iBlackHeight (0), 01472 comp_f () 01473 { 01474 // Mark the two fictitious nodes as dummies. 01475 beginNode.color = Node::DUMMY_BEGIN; 01476 endNode.color = Node::DUMMY_END; 01477 } 01478 01479 //--------------------------------------------------------- 01480 // Constructor with a pointer to comparison object. 01481 // 01482 template <class Type, class Compare, typename Allocator> 01483 Multiset<Type, Compare, Allocator>::Multiset (const Compare& comp) : 01484 rootP (NULL), 01485 iSize (0), 01486 iBlackHeight (0), 01487 comp_f (comp) 01488 { 01489 // Mark the two fictitious nodes as dummies. 01490 beginNode.color = Node::DUMMY_BEGIN; 01491 endNode.color = Node::DUMMY_END; 01492 } 01493 01494 //--------------------------------------------------------- 01495 // Copy constructor. 01496 // 01497 template <class Type, class Compare, typename Allocator> 01498 Multiset<Type, Compare, Allocator>::Multiset (const Self& tree) : 01499 rootP (NULL), 01500 iSize (tree.iSize), 01501 iBlackHeight (tree.iBlackHeight), 01502 comp_f (tree.comp_f) 01503 { 01504 // Mark the two fictitious nodes as dummies. 01505 beginNode.color = Node::DUMMY_BEGIN; 01506 endNode.color = Node::DUMMY_END; 01507 01508 // Copy all the copied tree's nodes recursively. 01509 if (tree.rootP != NULL) 01510 { 01511 rootP = _duplicate (tree.rootP); 01512 01513 // Set the dummy nodes. 01514 beginNode.parentP = _sub_minimum (rootP); 01515 beginNode.parentP->leftP = &beginNode; 01516 endNode.parentP = _sub_maximum (rootP); 01517 endNode.parentP->rightP = &endNode; 01518 } 01519 else 01520 { 01521 beginNode.parentP = NULL; 01522 endNode.parentP = NULL; 01523 } 01524 } 01525 01526 //--------------------------------------------------------- 01527 // Destructor. 01528 // 01529 template <class Type, class Compare, typename Allocator> 01530 Multiset<Type, Compare, Allocator>::~Multiset () 01531 { 01532 // Delete the entire tree recursively. 01533 if (rootP != NULL) 01534 _destroy (rootP); 01535 01536 rootP = NULL; 01537 beginNode.parentP = NULL; 01538 endNode.parentP = NULL; 01539 } 01540 01541 //--------------------------------------------------------- 01542 // Assignment operator. 01543 // 01544 template <class Type, class Compare, typename Allocator> 01545 Multiset<Type, Compare, Allocator>& 01546 Multiset<Type, Compare, Allocator>::operator= (const Self& tree) 01547 { 01548 // Avoid self-assignment. 01549 if (this == &tree) 01550 return (*this); 01551 01552 // Free all objects currently stored in the tree. 01553 clear(); 01554 01555 // Update the number of objects stored in the tree. 01556 iSize = tree.iSize; 01557 iBlackHeight = tree.iBlackHeight; 01558 01559 // Copy all the copied tree's nodes recursively. 01560 if (tree.rootP != NULL) 01561 { 01562 rootP = _duplicate (tree.rootP); 01563 01564 // Set the dummy nodes. 01565 beginNode.parentP = _sub_minimum (rootP); 01566 beginNode.parentP->leftP = &beginNode; 01567 endNode.parentP = _sub_maximum (rootP); 01568 endNode.parentP->rightP = &endNode; 01569 } 01570 else 01571 { 01572 beginNode.parentP = NULL; 01573 endNode.parentP = NULL; 01574 } 01575 01576 return (*this); 01577 } 01578 01579 //--------------------------------------------------------- 01580 // Swap two trees (replace their contents). 01581 // 01582 template <class Type, class Compare, typename Allocator> 01583 void Multiset<Type, Compare, Allocator>::swap (Self& tree) 01584 { 01585 // Avoid self-swapping. 01586 if (this == &tree) 01587 return; 01588 01589 // Replace the contents of the trees. 01590 Node *tempP = rootP; 01591 rootP = tree.rootP; 01592 tree.rootP = tempP; 01593 01594 size_t iTemp = iSize; 01595 iSize = tree.iSize; 01596 tree.iSize = iTemp; 01597 01598 iTemp = iBlackHeight; 01599 iBlackHeight = tree.iBlackHeight; 01600 tree.iBlackHeight = iTemp; 01601 01602 // Update the fictitious begin and end nodes. 01603 tempP = beginNode.parentP; 01604 beginNode.parentP = tree.beginNode.parentP; 01605 if (beginNode.parentP != NULL) 01606 beginNode.parentP->leftP = &beginNode; 01607 tree.beginNode.parentP = tempP; 01608 if (tree.beginNode.parentP != NULL) 01609 tree.beginNode.parentP->leftP = &(tree.beginNode); 01610 01611 tempP = endNode.parentP; 01612 endNode.parentP = tree.endNode.parentP; 01613 if (endNode.parentP != NULL) 01614 endNode.parentP->rightP = &endNode; 01615 tree.endNode.parentP = tempP; 01616 if (tree.endNode.parentP != NULL) 01617 tree.endNode.parentP->rightP = &(tree.endNode); 01618 01619 return; 01620 } 01621 01622 //--------------------------------------------------------- 01623 // Test two trees for equality. 01624 // 01625 template <class Type, class Compare, typename Allocator> 01626 bool Multiset<Type,Compare,Allocator>::operator== (const Self& tree) const 01627 { 01628 // The sizes of the two trees must be the same. 01629 if (size() != tree.size()) 01630 return (false); 01631 01632 // Go over all elements in both tree and compare them pairwise. 01633 const_iterator it1 = this->begin(); 01634 const_iterator it2 = tree.begin(); 01635 01636 while (it1 != this->end() && it2 != tree.end()) 01637 { 01638 if (comp_f (*it1, *it2) != EQUAL) 01639 return (false); 01640 01641 ++it1; 01642 ++it2; 01643 } 01644 01645 // If we reached here, the two trees are equal. 01646 return (true); 01647 } 01648 01649 //--------------------------------------------------------- 01650 // Check if our tree is lexicographically smaller that a given tree. 01651 // 01652 template <class Type, class Compare, typename Allocator> 01653 bool Multiset<Type,Compare,Allocator>::operator< (const Self& tree) const 01654 { 01655 // Go over all elements in both tree and compare them pairwise. 01656 const_iterator it1 = this->begin(); 01657 const_iterator it2 = tree.begin(); 01658 01659 while (it1 != this->end() && it2 != tree.end()) 01660 { 01661 const Comparison_result res = comp_f (*it1, *it2); 01662 01663 if (res == SMALLER) 01664 return (true); 01665 if (res == LARGER) 01666 return (false); 01667 01668 ++it1; 01669 ++it2; 01670 } 01671 01672 // If we reached here, one tree is the prefix of the other tree. We now 01673 // check which tree contains more elements. 01674 if (it1 != this->end()) 01675 { 01676 // Our tree contains the other tree as a prefix, so it is not smaller. 01677 return (false); 01678 } 01679 else if (it2 != tree.end()) 01680 { 01681 // The other tree contains our tree as a prefix, so our tree is smaller. 01682 return (true); 01683 } 01684 01685 // The two trees are equal: 01686 return (false); 01687 } 01688 01689 //--------------------------------------------------------- 01690 // Get an iterator for the minimum object in the tree (non-const version). 01691 // 01692 template <class Type, class Compare, typename Allocator> 01693 inline typename Multiset<Type,Compare,Allocator>::iterator 01694 Multiset<Type, Compare, Allocator>::begin () 01695 { 01696 if (beginNode.parentP != NULL) 01697 return (iterator (beginNode.parentP)); 01698 else 01699 return (iterator (&endNode)); 01700 } 01701 01702 //--------------------------------------------------------- 01703 // Get a past-the-end iterator for the tree objects (non-const version). 01704 // 01705 template <class Type, class Compare, typename Allocator> 01706 inline typename Multiset<Type, Compare,Allocator>::iterator 01707 Multiset<Type, Compare, Allocator>::end () 01708 { 01709 return (iterator (&endNode)); 01710 } 01711 01712 //--------------------------------------------------------- 01713 // Get an iterator for the minimum object in the tree (const version). 01714 // 01715 template <class Type, class Compare, typename Allocator> 01716 inline typename Multiset<Type,Compare,Allocator>::const_iterator 01717 Multiset<Type, Compare, Allocator>::begin () const 01718 { 01719 if (beginNode.parentP != NULL) 01720 return (const_iterator (beginNode.parentP)); 01721 else 01722 return (const_iterator (&endNode)); 01723 } 01724 01725 //--------------------------------------------------------- 01726 // Get a past-the-end iterator for the tree objects (const version). 01727 // 01728 template <class Type, class Compare, typename Allocator> 01729 inline typename Multiset<Type,Compare,Allocator>::const_iterator 01730 Multiset<Type, Compare, Allocator>::end () const 01731 { 01732 return (const_iterator (&endNode)); 01733 } 01734 01735 //--------------------------------------------------------- 01736 // Get a reverse iterator for the maxnimum object in the tree 01737 // (non-const version). 01738 // 01739 template <class Type, class Compare, typename Allocator> 01740 inline typename Multiset<Type,Compare,Allocator>::reverse_iterator 01741 Multiset<Type, Compare, Allocator>::rbegin () 01742 { 01743 return (reverse_iterator (end())); 01744 } 01745 01746 //--------------------------------------------------------- 01747 // Get a pre-the-begin reverse iterator for the tree objects 01748 // (non-const version). 01749 // 01750 template <class Type, class Compare, typename Allocator> 01751 inline typename Multiset<Type,Compare,Allocator>::reverse_iterator 01752 Multiset<Type, Compare, Allocator>::rend () 01753 { 01754 return (reverse_iterator (begin())); 01755 } 01756 01757 //--------------------------------------------------------- 01758 // Get a reverse iterator for the maximum object in the tree (const version). 01759 // 01760 template <class Type, class Compare, typename Allocator> 01761 inline typename Multiset<Type,Compare,Allocator>::const_reverse_iterator 01762 Multiset<Type, Compare, Allocator>::rbegin () const 01763 { 01764 return (const_reverse_iterator (end())); 01765 } 01766 01767 //--------------------------------------------------------- 01768 // Get a pre-the-begin reverse iterator for the tree objects (const version). 01769 // 01770 template <class Type, class Compare, typename Allocator> 01771 inline typename Multiset<Type,Compare,Allocator>::const_reverse_iterator 01772 Multiset<Type, Compare, Allocator>::rend () const 01773 { 01774 return (const_reverse_iterator (begin())); 01775 } 01776 01777 //--------------------------------------------------------- 01778 // Get the size of the tree. 01779 // 01780 template <class Type, class Compare, typename Allocator> 01781 size_t Multiset<Type, Compare, Allocator>::size () const 01782 { 01783 if (rootP == NULL) 01784 // The tree is empty: 01785 return (0); 01786 else if (iSize > 0) 01787 return (iSize); 01788 01789 // If we reached here, the tree is the result of a split operation and its 01790 // size is not known - compute it now. 01791 const Node *nodeP = beginNode.parentP; 01792 size_t iComputedSize = 0; 01793 01794 while (nodeP != &endNode) 01795 { 01796 nodeP = nodeP->successor(); 01797 iComputedSize++; 01798 } 01799 01800 // Assign the computed size. 01801 Self *myThis = const_cast<Self*> (this); 01802 myThis->iSize = iComputedSize; 01803 01804 return (iComputedSize); 01805 } 01806 01807 //--------------------------------------------------------- 01808 // Insert a new object to the tree. 01809 // 01810 template <class Type, class Compare, typename Allocator> 01811 typename Multiset<Type, Compare, Allocator>::iterator 01812 Multiset<Type, Compare, Allocator>::insert (const Type& object) 01813 { 01814 if (rootP == NULL) 01815 { 01816 // In case the tree is empty, assign a new rootP. 01817 // Notice that the root is always black. 01818 rootP = _allocate_node (object, Node::BLACK); 01819 01820 iSize = 1; 01821 iBlackHeight = 1; 01822 01823 // As the tree now contains a single node, it is both the tree 01824 // maximum and minimum. 01825 beginNode.parentP = rootP; 01826 rootP->leftP = &beginNode; 01827 endNode.parentP = rootP; 01828 rootP->rightP = &endNode; 01829 01830 return (iterator (rootP)); 01831 } 01832 01833 // Find a place for the new object, and insert it as a red leaf. 01834 Node *currentP = rootP; 01835 Node *newNodeP = _allocate_node (object, Node::RED); 01836 01837 Comparison_result comp_res; 01838 bool is_leftmost = true; 01839 bool is_rightmost = true; 01840 01841 while (_is_valid (currentP)) 01842 { 01843 // Compare the inserted object with the object stored in the current node. 01844 comp_res = comp_f (object, currentP->object); 01845 01846 if (comp_res == SMALLER) 01847 { 01848 is_rightmost = false; 01849 01850 if (! _is_valid (currentP->leftP)) 01851 { 01852 // Insert the new leaf as the left child of the current node. 01853 currentP->leftP = newNodeP; 01854 newNodeP->parentP = currentP; 01855 currentP = NULL; // In order to terminate the while loop. 01856 01857 if (is_leftmost) 01858 { 01859 // Assign a new tree minimum. 01860 beginNode.parentP = newNodeP; 01861 newNodeP->leftP = &beginNode; 01862 } 01863 } 01864 else 01865 { 01866 // Go to the left sub-tree. 01867 currentP = currentP->leftP; 01868 } 01869 } 01870 else 01871 { 01872 is_leftmost = false; 01873 01874 if (! _is_valid (currentP->rightP)) 01875 { 01876 // Insert the new leaf as the right child of the current node. 01877 currentP->rightP = newNodeP; 01878 newNodeP->parentP = currentP; 01879 currentP = NULL; // In order to terminate the while loop. 01880 01881 if (is_rightmost) 01882 { 01883 // Assign a new tree maximum. 01884 endNode.parentP = newNodeP; 01885 newNodeP->rightP = &endNode; 01886 } 01887 } 01888 else 01889 { 01890 // Go to the right sub-tree. 01891 currentP = currentP->rightP; 01892 } 01893 } 01894 } 01895 01896 // Mark that a new node was added. 01897 if (iSize > 0) 01898 iSize++; 01899 01900 // Fix up the tree properties. 01901 _insert_fixup (newNodeP); 01902 01903 return (iterator(newNodeP)); 01904 } 01905 01906 //--------------------------------------------------------- 01907 // Insert an object to the tree, with a given hint to its position. 01908 // 01909 template <class Type, class Compare, typename Allocator> 01910 typename Multiset<Type, Compare, Allocator>::iterator 01911 Multiset<Type, Compare, Allocator>::insert (iterator position, 01912 const Type& object) 01913 { 01914 Node *nodeP = position.nodeP; 01915 01916 CGAL_multiset_precondition (_is_valid (nodeP)); 01917 01918 // Compare the object to the one stored at the given node in order to decide 01919 // in which direction to proceed. 01920 const size_t max_steps = static_cast<size_t> (1.5 * iBlackHeight); 01921 Comparison_result res = comp_f(object, nodeP->object); 01922 bool found_pos = true; 01923 size_t k = 0; 01924 01925 if (res == EQUAL) 01926 return (insert_after (position, object)); 01927 01928 if (res == SMALLER) 01929 { 01930 // Go back until locating an object not greater than the inserted one. 01931 Node *predP = nodeP->predecessor(); 01932 01933 while (_is_valid (predP) && 01934 comp_f (object, predP->object) == SMALLER) 01935 { 01936 k++; 01937 if (k > max_steps) 01938 { 01939 // In case the given position is too far away (more than log(n) steps) 01940 // from the true poisition of the object, break the loop. 01941 found_pos = false; 01942 break; 01943 } 01944 01945 nodeP = predP; 01946 predP = nodeP->predecessor(); 01947 } 01948 01949 if (found_pos) 01950 return (insert_before (iterator (nodeP), object)); 01951 } 01952 else 01953 { 01954 // Go forward until locating an object not less than the inserted one. 01955 Node *succP = nodeP->successor(); 01956 01957 while (_is_valid (succP) && 01958 comp_f (object, succP->object) == LARGER) 01959 { 01960 k++; 01961 if (k > max_steps) 01962 { 01963 // In case the given position is too far away (more than log(n) steps) 01964 // from the true poisition of the object, break the loop. 01965 found_pos = false; 01966 break; 01967 } 01968 01969 nodeP = succP; 01970 succP = nodeP->successor(); 01971 } 01972 01973 if (found_pos) 01974 return (insert_after (iterator (nodeP), object)); 01975 } 01976 01977 // If the hint was too far than the actual position, perform a normal 01978 // insertion: 01979 return (insert (object)); 01980 } 01981 01982 //--------------------------------------------------------- 01983 // Insert a new object to the tree as the a successor of a given node. 01984 // 01985 template <class Type, class Compare, typename Allocator> 01986 typename Multiset<Type, Compare, Allocator>::iterator 01987 Multiset<Type, Compare, Allocator>::insert_after (iterator position, 01988 const Type& object) 01989 { 01990 Node *nodeP = position.nodeP; 01991 01992 // In case we are given a NULL node, object should be the tree minimum. 01993 CGAL_multiset_assertion (nodeP != &endNode); 01994 01995 if (nodeP == &beginNode) 01996 nodeP = NULL; 01997 01998 if (rootP == NULL) 01999 { 02000 // In case the tree is empty, make sure that we did not recieve a valid 02001 // iterator. 02002 CGAL_multiset_precondition (nodeP == NULL); 02003 02004 // Assign a new root node. Notice that the root is always black. 02005 rootP = _allocate_node (object, Node::BLACK); 02006 02007 iSize = 1; 02008 iBlackHeight = 1; 02009 02010 // As the tree now contains a single node, it is both the tree 02011 // maximum and minimum: 02012 beginNode.parentP = rootP; 02013 rootP->leftP = &beginNode; 02014 endNode.parentP = rootP; 02015 rootP->rightP = &endNode; 02016 02017 return (iterator (rootP)); 02018 } 02019 02020 // Insert the new object as a red leaf, being the successor of nodeP. 02021 Node *parentP; 02022 Node *newNodeP = _allocate_node (object, Node::RED); 02023 02024 if (nodeP == NULL) 02025 { 02026 // The new node should become the tree minimum: Place is as the left 02027 // child of the current minimal leaf. 02028 parentP = beginNode.parentP; 02029 02030 CGAL_multiset_precondition (comp_f(object, parentP->object) != LARGER); 02031 02032 parentP->leftP = newNodeP; 02033 02034 // As we inserted a new tree minimum: 02035 beginNode.parentP = newNodeP; 02036 newNodeP->leftP = &beginNode; 02037 } 02038 else 02039 { 02040 // Make sure the insertion does not violate the tree order. 02041 CGAL_multiset_precondition_code (Node *_succP = nodeP->successor()); 02042 CGAL_multiset_precondition (comp_f(object, nodeP->object) != SMALLER); 02043 CGAL_multiset_precondition (! _succP->is_valid() || 02044 comp_f(object, _succP->object) != LARGER); 02045 02046 // In case given node has no right child, place the new node as its 02047 // right child. Otherwise, place it at the leftmost position at the 02048 // sub-tree rooted at its right side. 02049 if (! _is_valid (nodeP->rightP)) 02050 { 02051 parentP = nodeP; 02052 parentP->rightP = newNodeP; 02053 } 02054 else 02055 { 02056 parentP = _sub_minimum (nodeP->rightP); 02057 parentP->leftP = newNodeP; 02058 } 02059 02060 if (nodeP == endNode.parentP) 02061 { 02062 // As we inserted a new tree maximum: 02063 endNode.parentP = newNodeP; 02064 newNodeP->rightP = &endNode; 02065 } 02066 } 02067 02068 newNodeP->parentP = parentP; 02069 02070 // Mark that a new node was added. 02071 if (iSize > 0) 02072 iSize++; 02073 02074 // Fix up the tree properties. 02075 _insert_fixup (newNodeP); 02076 02077 return (iterator (newNodeP)); 02078 } 02079 02080 //--------------------------------------------------------- 02081 // Insert a new object to the tree as the a predecessor of a given node. 02082 // 02083 template <class Type, class Compare, typename Allocator> 02084 typename Multiset<Type, Compare, Allocator>::iterator 02085 Multiset<Type, Compare, Allocator>::insert_before (iterator position, 02086 const Type& object) 02087 { 02088 Node *nodeP = position.nodeP; 02089 02090 // In case we are given a NULL node, object should be the tree maximum. 02091 CGAL_multiset_assertion (nodeP != &beginNode); 02092 02093 if (nodeP == &endNode) 02094 nodeP = NULL; 02095 02096 if (rootP == NULL) 02097 { 02098 // In case the tree is empty, make sure that we did not recieve a valid 02099 // iterator. 02100 CGAL_multiset_precondition (nodeP == NULL); 02101 02102 // Assign a new root node. Notice that the root is always black. 02103 rootP = _allocate_node(object, Node::BLACK); 02104 02105 iSize = 1; 02106 iBlackHeight = 1; 02107 02108 // As the tree now contains a single node, it is both the tree 02109 // maximum and minimum: 02110 beginNode.parentP = rootP; 02111 rootP->leftP = &beginNode; 02112 endNode.parentP = rootP; 02113 rootP->rightP = &endNode; 02114 02115 return (iterator (rootP)); 02116 } 02117 02118 // Insert the new object as a red leaf, being the predecessor of nodeP. 02119 Node *parentP; 02120 Node *newNodeP = _allocate_node (object, Node::RED); 02121 02122 if (nodeP == NULL) 02123 { 02124 // The new node should become the tree maximum: Place is as the right 02125 // child of the current maximal leaf. 02126 parentP = endNode.parentP; 02127 02128 CGAL_multiset_precondition (comp_f(object, parentP->object) != SMALLER); 02129 02130 parentP->rightP = newNodeP; 02131 02132 // As we inserted a new tree maximum: 02133 endNode.parentP = newNodeP; 02134 newNodeP->rightP = &endNode; 02135 } 02136 else 02137 { 02138 // Make sure the insertion does not violate the tree order. 02139 CGAL_multiset_precondition_code (Node *_predP = nodeP->predecessor()); 02140 CGAL_multiset_precondition (comp_f(object, nodeP->object) != LARGER); 02141 CGAL_multiset_precondition (! _predP->is_valid() || 02142 comp_f(object, _predP->object) != SMALLER); 02143 02144 // In case given node has no left child, place the new node as its 02145 // left child. Otherwise, place it at the rightmost position at the 02146 // sub-tree rooted at its left side. 02147 if (! _is_valid (nodeP->leftP)) 02148 { 02149 parentP = nodeP; 02150 parentP->leftP = newNodeP; 02151 } 02152 else 02153 { 02154 parentP = _sub_maximum (nodeP->leftP); 02155 parentP->rightP = newNodeP; 02156 } 02157 02158 if (nodeP == beginNode.parentP) 02159 { 02160 // As we inserted a new tree minimum: 02161 beginNode.parentP = newNodeP; 02162 newNodeP->leftP = &beginNode; 02163 } 02164 } 02165 02166 newNodeP->parentP = parentP; 02167 02168 // Mark that a new node was added. 02169 if (iSize > 0) 02170 iSize++; 02171 02172 // Fix up the tree properties. 02173 _insert_fixup (newNodeP); 02174 02175 return (iterator (newNodeP)); 02176 } 02177 02178 //--------------------------------------------------------- 02179 // Remove an object from the tree. 02180 // 02181 template <class Type, class Compare, typename Allocator> 02182 size_t Multiset<Type, Compare, Allocator>::erase (const Type& object) 02183 { 02184 // Find the first node containing an object not less than the object to 02185 // be erased and from there look for objects equivalent to the given object. 02186 size_t n_removed = 0; 02187 bool is_equal; 02188 Node *nodeP = _bound (LOWER_BOUND, object, comp_f, is_equal); 02189 Node *succP; 02190 02191 if (! is_equal) 02192 return (n_removed); 02193 02194 while (_is_valid (nodeP) && comp_f (object, nodeP->object) == EQUAL) 02195 { 02196 // Keep a pointer to the successor node. 02197 succP = nodeP->successor(); 02198 02199 // Remove the current node. 02200 _remove_at (nodeP); 02201 n_removed++; 02202 02203 // Proceed to the successor. 02204 nodeP = succP; 02205 } 02206 02207 return (n_removed); 02208 } 02209 02210 //--------------------------------------------------------- 02211 // Remove the object pointed by the given iterator. 02212 // 02213 template <class Type, class Compare, typename Allocator> 02214 void Multiset<Type, Compare, Allocator>::erase (iterator position) 02215 { 02216 Node *nodeP = position.nodeP; 02217 02218 CGAL_multiset_precondition (_is_valid (nodeP)); 02219 02220 _remove_at (nodeP); 02221 return; 02222 } 02223 02224 //--------------------------------------------------------- 02225 // Remove all objects from the tree. 02226 // 02227 template <class Type, class Compare, typename Allocator> 02228 void Multiset<Type, Compare, Allocator>::clear () 02229 { 02230 // Delete all the tree nodes recursively. 02231 if (rootP != NULL) 02232 _destroy (rootP); 02233 02234 rootP = NULL; 02235 beginNode.parentP = NULL; 02236 endNode.parentP = NULL; 02237 02238 // Mark that there are no more objects in the tree. 02239 iSize = 0; 02240 iBlackHeight = 0; 02241 02242 return; 02243 } 02244 02245 //--------------------------------------------------------- 02246 // Replace the object pointed by a given iterator with another object. 02247 // 02248 template <class Type, class Compare, typename Allocator> 02249 void Multiset<Type, Compare, Allocator>::replace (iterator position, 02250 const Type& object) 02251 { 02252 Node *nodeP = position.nodeP; 02253 02254 CGAL_multiset_precondition (_is_valid (nodeP)); 02255 02256 // Make sure the replacement does not violate the tree order. 02257 CGAL_multiset_precondition_code (Node *_succP = nodeP->successor()); 02258 CGAL_multiset_precondition (_succP == NULL || 02259 _succP->color == Node::DUMMY_END || 02260 comp_f(object, _succP->object) != LARGER); 02261 02262 CGAL_multiset_precondition_code (Node *_predP = nodeP->predecessor()); 02263 CGAL_multiset_precondition (_predP == NULL || 02264 _predP->color == Node::DUMMY_BEGIN || 02265 comp_f(object, _predP->object) != SMALLER); 02266 02267 // Replace the object at nodeP. 02268 nodeP->object = object; 02269 02270 return; 02271 } 02272 02273 //--------------------------------------------------------- 02274 // Swap the location two objects in the tree, given by their positions. 02275 // 02276 template <class Type, class Compare, typename Allocator> 02277 void Multiset<Type, Compare, Allocator>::swap (iterator pos1, 02278 iterator pos2) 02279 { 02280 Node *node1_P = pos1.nodeP; 02281 Node *node2_P = pos2.nodeP; 02282 02283 CGAL_multiset_precondition (_is_valid (node1_P)); 02284 CGAL_multiset_precondition (_is_valid (node2_P)); 02285 02286 if (node1_P == node2_P) 02287 return; 02288 02289 // Make sure the swap does not violate the tree order. 02290 CGAL_multiset_precondition_code (Node *_succ1_P = node1_P->successor()); 02291 CGAL_multiset_precondition (! _is_valid (_succ1_P) || 02292 comp_f (node2_P->object, 02293 _succ1_P->object) != LARGER); 02294 02295 CGAL_multiset_precondition_code (Node *_pred1_P = node1_P->predecessor()); 02296 CGAL_multiset_precondition (! _is_valid (_pred1_P) || 02297 comp_f (node2_P->object, 02298 _pred1_P->object) != SMALLER); 02299 02300 CGAL_multiset_precondition_code (Node *_succ2_P = node2_P->successor()); 02301 CGAL_multiset_precondition (! _is_valid (_succ2_P) || 02302 comp_f (node1_P->object, 02303 _succ2_P->object) != LARGER); 02304 02305 CGAL_multiset_precondition_code (Node *_pred2_P = node2_P->predecessor()); 02306 CGAL_multiset_precondition (! _is_valid (_pred2_P) || 02307 comp_f (node1_P->object, 02308 _pred2_P->object) != SMALLER); 02309 02310 // Perform the swap. 02311 if (node1_P->parentP == node2_P->parentP) 02312 _swap_siblings (node1_P, node2_P); 02313 else 02314 _swap (node1_P, node2_P); 02315 02316 return; 02317 } 02318 02319 //--------------------------------------------------------- 02320 // Check if the tree is a valid one. 02321 // 02322 template <class Type, class Compare, typename Allocator> 02323 bool Multiset<Type, Compare, Allocator>::is_valid () const 02324 { 02325 if (rootP == NULL) 02326 { 02327 // If there is no root, make sure that the tree is empty. 02328 if (iSize != 0 || iBlackHeight != 0) 02329 return (false); 02330 02331 if (beginNode.parentP != NULL || endNode.parentP != NULL) 02332 return (false); 02333 02334 return (true); 02335 } 02336 02337 // Check the validity of the fictitious nodes. 02338 if (beginNode.parentP == NULL || beginNode.parentP->leftP != &beginNode) 02339 return (false); 02340 02341 if (endNode.parentP == NULL || endNode.parentP->rightP != &endNode) 02342 return (false); 02343 02344 // Check recursively whether the tree is valid. 02345 size_t iComputedSize; 02346 size_t iComputedBHeight; 02347 02348 if (! _sub_is_valid (rootP, iComputedSize, iComputedBHeight)) 02349 return (false); 02350 02351 // Make sure the tree properties are correct. 02352 if (iSize != 0) 02353 { 02354 if (iSize != iComputedSize) 02355 return (false); 02356 } 02357 else 02358 { 02359 // Assign the computed size. 02360 Self *myThis = const_cast<Self*> (this); 02361 myThis->iSize = iComputedSize; 02362 } 02363 02364 if (iBlackHeight != iComputedBHeight) 02365 return (false); 02366 02367 // If we reached here, the entire tree is valid. 02368 return (true); 02369 } 02370 02371 //--------------------------------------------------------- 02372 // Get the height of the tree. 02373 // 02374 template <class Type, class Compare, typename Allocator> 02375 size_t Multiset<Type, Compare, Allocator>::height () const 02376 { 02377 if (rootP == NULL) 02378 // Empty tree. 02379 return (0); 02380 02381 // Return the height of the root's sub-tree (the entire tree). 02382 return (_sub_height (rootP)); 02383 } 02384 02385 //--------------------------------------------------------- 02386 // Catenate the tree with another given tree. 02387 // 02388 template <class Type, class Compare, typename Allocator> 02389 void Multiset<Type, Compare, Allocator>::catenate (Self& tree) 02390 { 02391 // Get the maximal node in our tree and the minimal node in the other tree. 02392 Node *max1_P = endNode.parentP; 02393 Node *min2_P = tree.beginNode.parentP; 02394 02395 if (min2_P == NULL) 02396 { 02397 // The other tree is empty - nothing to do. 02398 CGAL_multiset_assertion (tree.rootP == NULL); 02399 return; 02400 } 02401 else if (max1_P == NULL) 02402 { 02403 // Our tree is empty: Copy all other tree properties to our tree. 02404 CGAL_multiset_assertion (rootP == NULL); 02405 02406 _shallow_assign (tree); 02407 return; 02408 } 02409 02410 // Make sure that the minimal object in the other tree is not less than the 02411 // maximal object in our tree. 02412 CGAL_multiset_precondition (comp_f (max1_P->object, 02413 min2_P->object) != LARGER); 02414 02415 // Make sure both tree roots black. 02416 CGAL_multiset_assertion (_is_black (rootP)); 02417 CGAL_multiset_assertion (_is_black (tree.rootP)); 02418 02419 // Splice max1_P (or min2_P) from its tree, but without deleting it. 02420 Node* auxP = NULL; 02421 02422 if (max1_P != rootP) 02423 { 02424 // Splice max1_P from its current poisition in our tree. 02425 // We know it is has no right child, so we just have to connect its 02426 // left child with its parent. 02427 max1_P->parentP->rightP = max1_P->leftP; 02428 02429 if (_is_valid (max1_P->leftP)) 02430 max1_P->leftP->parentP = max1_P->parentP; 02431 02432 // If max1_P is a black node, we have to fixup our tree. 02433 if (max1_P->color == Node::BLACK) 02434 _remove_fixup (max1_P->leftP, max1_P->parentP); 02435 02436 auxP = max1_P; 02437 } 02438 else if (min2_P != tree.rootP) 02439 { 02440 // Splice min2_P from its current poisition in the other tree. 02441 // We know it is has no left child, so we just have to connect its 02442 // right child with its parent. 02443 if (min2_P->parentP != NULL) 02444 { 02445 min2_P->parentP->leftP = min2_P->rightP; 02446 02447 if (_is_valid (min2_P->rightP)) 02448 min2_P->rightP->parentP = min2_P->parentP; 02449 02450 // If min2_P is a black node, we have to fixup the other tree. 02451 if (min2_P->color == Node::BLACK) 02452 tree._remove_fixup (min2_P->rightP, min2_P->parentP); 02453 } 02454 02455 auxP = min2_P; 02456 } 02457 else 02458 { 02459 // Both nodes are root nodes: Assign min2_P as the right child of the 02460 // root and color it red. 02461 rootP->rightP = min2_P; 02462 min2_P->parentP = rootP; 02463 min2_P->color = Node::RED; 02464 min2_P->leftP = NULL; 02465 02466 if (! _is_valid (min2_P->rightP)) 02467 { 02468 // The other tree is of size 1 - set min2_P as the tree maximum. 02469 min2_P->rightP = &endNode; 02470 endNode.parentP = min2_P; 02471 } 02472 else 02473 { 02474 // The other tree is of size 2 - fixup from min2_P's right child and set 02475 // it as the tree maximum. 02476 _insert_fixup (min2_P->rightP); 02477 min2_P->rightP->rightP = &endNode; 02478 endNode.parentP = min2_P->rightP; 02479 } 02480 02481 if (iSize > 0 && tree.iSize > 0) 02482 iSize += tree.iSize; 02483 else 02484 iSize = 0; 02485 02486 // Clear the other tree (without actually deallocating the nodes). 02487 tree._shallow_clear(); 02488 02489 return; 02490 } 02491 02492 // Mark that the maximal node in our tree is no longer the maximum. 02493 if (endNode.parentP != NULL) 02494 endNode.parentP->rightP = NULL; 02495 02496 // Mark that the minimal node in the other tree is no longer the minimum. 02497 if (tree.beginNode.parentP != NULL) 02498 tree.beginNode.parentP->leftP = NULL; 02499 02500 // Locate node1_P along the rightmost path in our tree and node2_P along the 02501 // leftmost path in the other tree, both having the same black-height. 02502 Node *node1_P = rootP; 02503 Node *node2_P = tree.rootP; 02504 size_t iCurrBHeight; 02505 02506 if (iBlackHeight <= tree.iBlackHeight) 02507 { 02508 // The other tree is taller (or both trees have the same height): 02509 // Go down the leftmost path of the other tree and locate node2_P. 02510 node2_P = tree.rootP; 02511 iCurrBHeight = tree.iBlackHeight; 02512 while (iCurrBHeight > iBlackHeight) 02513 { 02514 if (node2_P->color == Node::BLACK) 02515 iCurrBHeight--; 02516 node2_P = node2_P->leftP; 02517 } 02518 02519 if (_is_red (node2_P)) 02520 node2_P = node2_P->leftP; 02521 CGAL_multiset_assertion (_is_valid (node2_P)); 02522 } 02523 else 02524 { 02525 // Our tree is taller: 02526 // Go down the rightmost path of our tree and locate node1_P. 02527 node1_P = rootP; 02528 iCurrBHeight = iBlackHeight; 02529 while (iCurrBHeight > tree.iBlackHeight) 02530 { 02531 if (node1_P->color == Node::BLACK) 02532 iCurrBHeight--; 02533 node1_P = node1_P->rightP; 02534 } 02535 02536 if (_is_red (node1_P)) 02537 node1_P = node1_P->rightP; 02538 CGAL_multiset_assertion (_is_valid (node2_P)); 02539 } 02540 02541 // Check which one of the tree roots have we reached. 02542 Node *newRootP = NULL; 02543 Node *parentP; 02544 02545 if (node1_P == rootP) 02546 { 02547 // We know that node2_P has the same number of black roots from it to 02548 // the minimal tree node as the number of black nodes from our tree root 02549 // to any of its leaves. We make rootP and node2_P siblings by moving 02550 // auxP to be their parent. 02551 parentP = node2_P->parentP; 02552 02553 if (parentP == NULL) 02554 { 02555 // Make auxP the root of the catenated tree. 02556 newRootP = auxP; 02557 } 02558 else 02559 { 02560 // The catenated tree will be rooted at the other tree's root. 02561 newRootP = tree.rootP; 02562 02563 // Move auxP as the left child of parentP. 02564 parentP->leftP = auxP; 02565 } 02566 } 02567 else 02568 { 02569 // We know that node1_P has the same number of black roots from it to 02570 // the maximal tree node as the number of black nodes from the other tree 02571 // root to any of its leaves. We make tree.rootP and node1_P siblings by 02572 // moving auxP to be their parent. 02573 parentP = node1_P->parentP; 02574 02575 CGAL_multiset_assertion (parentP != NULL); 02576 02577 // The catenated tree will be rooted at the current root of our tree. 02578 newRootP = rootP; 02579 02580 // Move auxP as the right child of parentP. 02581 parentP->rightP = auxP; 02582 } 02583 02584 // Move node1_P to be the left child of auxP, and node2_P to be its 02585 // right child. We also color this node red. 02586 auxP->parentP = parentP; 02587 auxP->color = Node::RED; 02588 auxP->leftP = node1_P; 02589 auxP->rightP = node2_P; 02590 02591 node1_P->parentP = auxP; 02592 node2_P->parentP = auxP; 02593 02594 // Set the catenated tree properties. 02595 if (rootP != newRootP) 02596 { 02597 // Take the black-height of the other tree. 02598 iBlackHeight = tree.iBlackHeight; 02599 rootP = newRootP; 02600 } 02601 02602 if (iSize > 0 && tree.iSize > 0) 02603 iSize += tree.iSize; 02604 else 02605 iSize = 0; 02606 02607 // Set the new maximal node in the tree (the minimal node remains unchanged). 02608 endNode.parentP = tree.endNode.parentP; 02609 endNode.parentP->rightP = &endNode; 02610 02611 // Clear the other tree (without actually deallocating the nodes). 02612 tree._shallow_clear(); 02613 02614 // Perform a fixup of the tree invariants. This fixup will also take care 02615 // of updating the black-height of our catenated tree. 02616 _insert_fixup (auxP); 02617 02618 return; 02619 } 02620 02621 //--------------------------------------------------------- 02622 // Split the tree at a given position, such that it contains all objects 02623 // in the range [begin, position) and all objects in the range 02624 // [position, end) form a new output tree. 02625 // 02626 template <class Type, class Compare, typename Allocator> 02627 void Multiset<Type, Compare, Allocator>::split (iterator position, 02628 Self& tree) 02629 { 02630 CGAL_multiset_precondition (tree.empty()); 02631 02632 // Check the extremal cases. 02633 if (position == begin()) 02634 { 02635 // The tree should be copied to the output tree. 02636 tree._shallow_assign (*this); 02637 return; 02638 } 02639 else if (position == end()) 02640 { 02641 // Nothing to do - all objects should remain in our tree. 02642 return; 02643 } 02644 02645 // Prepare a vector describing the path from the given node to the tree 02646 // root (where SMALLER designates a left turn and LARGER designates a 02647 // right turn). Note that the length of this path (the depth of nodeP) 02648 // is at most twice the black-height of the tree. 02649 Node *nodeP = position.nodeP; 02650 02651 CGAL_multiset_precondition (_is_valid (nodeP)); 02652 02653 Node *currP = nodeP; 02654 Comparison_result *path = new Comparison_result [2 * iBlackHeight]; 02655 int depth = 0; 02656 02657 path[depth] = EQUAL; 02658 while (currP->parentP != NULL) 02659 { 02660 depth++; 02661 if (currP == currP->parentP->leftP) 02662 path[depth] = SMALLER; 02663 else 02664 path[depth] = LARGER; 02665 02666 currP = currP->parentP; 02667 } 02668 CGAL_multiset_assertion (currP == rootP); 02669 02670 // Now go down the path and split the tree accordingly. We also keep 02671 // track of the black-height of the current node. 02672 size_t iCurrBHeight = iBlackHeight; 02673 Self leftTree; 02674 size_t iLeftBHeight = 0; 02675 Node *spineLeftP = NULL; 02676 Node *auxLeftP = NULL; 02677 Self rightTree; 02678 size_t iRightBHeight = 0; 02679 Node *spineRightP = NULL; 02680 Node *auxRightP = NULL; 02681 Node *childP = NULL; 02682 Node *nextP = NULL; 02683 02684 while (depth >= 0) 02685 { 02686 CGAL_multiset_assertion (_is_valid (currP)); 02687 02688 // If we encounter a black node, the black-height of both its left and 02689 // right subtrees is decremented. 02690 if (_is_black (currP)) 02691 iCurrBHeight--; 02692 02693 // Check in which direction we have to go. 02694 if (path[depth] != LARGER) 02695 { 02696 // We go left, so currP and its entire right sub-tree (T_r) should be 02697 // included in the right split tree. 02698 // 02699 // (.) currP . 02700 // / \ . 02701 // / \ . 02702 // (.) T_r . 02703 // 02704 // This also covers that case where currP is the split node (nodeP). 02705 childP = currP->rightP; 02706 nextP = currP->leftP; 02707 02708 if (_is_valid (childP) && rightTree.rootP == NULL) 02709 { 02710 // Assing T_r to rightTree. 02711 rightTree.rootP = childP; 02712 rightTree.iBlackHeight = iCurrBHeight; 02713 02714 // Make sure the root of rightTree is black. 02715 rightTree.rootP->parentP = NULL; 02716 if (_is_red (rightTree.rootP)) 02717 { 02718 rightTree.rootP->color = Node::BLACK; 02719 rightTree.iBlackHeight++; 02720 } 02721 02722 // We store a black node along the leftmost spine of rightTree whose 02723 // black-hieght is exactly iRightBHeight. 02724 iRightBHeight = rightTree.iBlackHeight; 02725 spineRightP = rightTree.rootP; 02726 } 02727 else if (_is_valid (childP)) 02728 { 02729 // Catenate T_r with the current rightTree. 02730 CGAL_multiset_assertion (_is_valid (spineRightP) && 02731 _is_valid(auxRightP)); 02732 02733 // Make sure the root of T_r is black. 02734 size_t iCurrRightBHeight = iCurrBHeight; 02735 02736 if (_is_red (childP)) 02737 { 02738 childP->color = Node::BLACK; 02739 iCurrRightBHeight++; 02740 } 02741 02742 // Go down the leftmost path of rightTree until locating a black 02743 // node whose black height is exactly iCurrRightBHeight. 02744 CGAL_multiset_assertion (iRightBHeight >= iCurrRightBHeight); 02745 02746 while (iRightBHeight > iCurrRightBHeight) 02747 { 02748 if (spineRightP->color == Node::BLACK) 02749 iRightBHeight--; 02750 spineRightP = spineRightP->leftP; 02751 } 02752 02753 if (_is_red (spineRightP)) 02754 spineRightP = spineRightP->leftP; 02755 CGAL_multiset_assertion (_is_valid (spineRightP)); 02756 02757 // Use the auxiliary node and make it the parent of T_r (which 02758 // becomes its left sub-tree) and spineRightP (which becomes its 02759 // right child). We color the auxiliary node red, as both its 02760 // children are black. 02761 auxRightP->parentP = spineRightP->parentP; 02762 auxRightP->color = Node::RED; 02763 auxRightP->leftP = childP; 02764 auxRightP->rightP = spineRightP; 02765 02766 if (auxRightP->parentP != NULL) 02767 auxRightP->parentP->leftP = auxRightP; 02768 else 02769 rightTree.rootP = auxRightP; 02770 02771 childP->parentP = auxRightP; 02772 spineRightP->parentP = auxRightP; 02773 02774 // Perform a fixup on the right tree. 02775 rightTree._insert_fixup (auxRightP); 02776 auxRightP = NULL; 02777 02778 // Note that childP is now located on the leftmost spine of 02779 // rightTree and its black-height is exactly iCurrRightBHeight. 02780 iRightBHeight = iCurrRightBHeight; 02781 spineRightP = childP; 02782 } 02783 02784 // In case we have an auxiliary right node that has not been inserted 02785 // into the right tree, insert it now. 02786 if (auxRightP != NULL) 02787 { 02788 if (rightTree.rootP != NULL) 02789 { 02790 // The right tree is not empty. Traverse its leftmost spine to 02791 // locate the parent of auxRightP. 02792 while (_is_valid (spineRightP->leftP)) 02793 spineRightP = spineRightP->leftP; 02794 02795 auxRightP->parentP = spineRightP; 02796 auxRightP->color = Node::RED; 02797 auxRightP->rightP = NULL; 02798 auxRightP->leftP = NULL; 02799 02800 spineRightP->leftP = auxRightP; 02801 02802 // Perform a fixup on the right tree, following the insertion of 02803 // the auxiliary right node. 02804 rightTree._insert_fixup (auxRightP); 02805 } 02806 else 02807 { 02808 // auxRightP is the only node in the current right tree. 02809 rightTree.rootP = auxRightP; 02810 rightTree.iBlackHeight = 1; 02811 02812 auxRightP->parentP = NULL; 02813 auxRightP->color = Node::BLACK; 02814 auxRightP->rightP = NULL; 02815 auxRightP->leftP = NULL; 02816 } 02817 02818 // Assign spineRightP to be the auxiliary node. 02819 spineRightP = auxRightP; 02820 iRightBHeight = (_is_black (spineRightP)) ? 1 : 0; 02821 auxRightP = NULL; 02822 } 02823 02824 // Mark currP as the auxiliary right node. 02825 auxRightP = currP; 02826 } 02827 02828 if (path[depth] != SMALLER) 02829 { 02830 // We go right, so currP and its entire left sub-tree (T_l) should be 02831 // included in the left split tree. 02832 // 02833 // (.) currP . 02834 // / \ . 02835 // / \ . 02836 // T_l (.) . 02837 // 02838 // An exception to this rule is when currP is the split node (nodeP), 02839 // so it should not be included in the left tree. 02840 childP = currP->leftP; 02841 nextP = currP->rightP; 02842 02843 if (_is_valid (childP) && leftTree.rootP == NULL) 02844 { 02845 // Assing T_l to leftTree. 02846 leftTree.rootP = childP; 02847 leftTree.iBlackHeight = iCurrBHeight; 02848 02849 // Make sure the root of leftTree is black. 02850 leftTree.rootP->parentP = NULL; 02851 if (_is_red (leftTree.rootP)) 02852 { 02853 leftTree.rootP->color = Node::BLACK; 02854 leftTree.iBlackHeight++; 02855 } 02856 02857 // We store a black node along the rightmost spine of leftTree whose 02858 // black-hieght is exactly iLeftBHeight. 02859 iLeftBHeight = leftTree.iBlackHeight; 02860 spineLeftP = leftTree.rootP; 02861 } 02862 else if (_is_valid (childP)) 02863 { 02864 // Catenate T_l with the current leftTree. 02865 CGAL_multiset_assertion (_is_valid (spineLeftP) && 02866 _is_valid(auxLeftP)); 02867 02868 // Make sure the root of T_l is black. 02869 size_t iCurrLeftBHeight = iCurrBHeight; 02870 02871 if (_is_red (childP)) 02872 { 02873 childP->color = Node::BLACK; 02874 iCurrLeftBHeight++; 02875 } 02876 02877 // Go down the rightmost path of leftTree until locating a black 02878 // node whose black height is exactly iCurrLeftBHeight. 02879 CGAL_multiset_assertion (iLeftBHeight >= iCurrLeftBHeight); 02880 02881 while (iLeftBHeight > iCurrLeftBHeight) 02882 { 02883 if (spineLeftP->color == Node::BLACK) 02884 iLeftBHeight--; 02885 spineLeftP = spineLeftP->rightP; 02886 } 02887 02888 if (_is_red (spineLeftP)) 02889 spineLeftP = spineLeftP->rightP; 02890 CGAL_multiset_assertion (_is_valid (spineLeftP)); 02891 02892 // Use the auxiliary node and make it the parent of T_l (which 02893 // becomes its right sub-tree) and spineLeftP (which becomes its 02894 // left child). We color the auxiliary node red, as both its 02895 // children are black. 02896 auxLeftP->parentP = spineLeftP->parentP; 02897 auxLeftP->color = Node::RED; 02898 auxLeftP->leftP = spineLeftP; 02899 auxLeftP->rightP = childP; 02900 02901 if (auxLeftP->parentP != NULL) 02902 auxLeftP->parentP->rightP = auxLeftP; 02903 else 02904 leftTree.rootP = auxLeftP; 02905 02906 childP->parentP = auxLeftP; 02907 spineLeftP->parentP = auxLeftP; 02908 02909 // Perform a fixup on the left tree. 02910 leftTree._insert_fixup (auxLeftP); 02911 auxLeftP = NULL; 02912 02913 // Note that childP is now located on the rightmost spine of 02914 // leftTree and its black-height is exactly iCurrLeftBHeight. 02915 iLeftBHeight = iCurrLeftBHeight; 02916 spineLeftP = childP; 02917 } 02918 02919 // In case we have an auxiliary left node that has not been inserted 02920 // into the left tree, insert it now. 02921 if (auxLeftP != NULL) 02922 { 02923 if (leftTree.rootP != NULL) 02924 { 02925 // The left tree is not empty. Traverse its rightmost spine to 02926 // locate the parent of auxLeftP. 02927 while (_is_valid (spineLeftP->rightP)) 02928 spineLeftP = spineLeftP->rightP; 02929 02930 auxLeftP->parentP = spineLeftP; 02931 auxLeftP->color = Node::RED; 02932 auxLeftP->rightP = NULL; 02933 auxLeftP->leftP = NULL; 02934 02935 spineLeftP->rightP = auxLeftP; 02936 02937 // Perform a fixup on the left tree, following the insertion of 02938 // the auxiliary left node. 02939 leftTree._insert_fixup (auxLeftP); 02940 } 02941 else 02942 { 02943 // auxLeftP is the only node in the left tree. 02944 leftTree.rootP = auxLeftP; 02945 leftTree.iBlackHeight = 1; 02946 02947 auxLeftP->parentP = NULL; 02948 auxLeftP->color = Node::BLACK; 02949 auxLeftP->rightP = NULL; 02950 auxLeftP->leftP = NULL; 02951 } 02952 02953 // Assign spineLeftP to be the auxiliary node. 02954 spineLeftP = auxLeftP; 02955 iLeftBHeight = (_is_black (spineLeftP)) ? 1 : 0; 02956 auxLeftP = NULL; 02957 } 02958 02959 // Mark currP as the auxiliary right node. 02960 if (depth > 0) 02961 auxLeftP = currP; 02962 } 02963 02964 // Proceed to the next step in the path. 02965 currP = nextP; 02966 depth--; 02967 } 02968 02969 // It is now possible to free the path. 02970 delete[] path; 02971 02972 CGAL_multiset_assertion (auxLeftP == NULL && auxRightP == nodeP); 02973 02974 // Fix the properties of the left tree: We know its minimal node is the 02975 // same as the current minimum. 02976 leftTree.beginNode.parentP = beginNode.parentP; 02977 leftTree.beginNode.parentP->leftP = &(leftTree.beginNode); 02978 02979 // Traverse the rightmost path of the left tree to find the its maximum. 02980 CGAL_multiset_assertion (_is_valid (spineLeftP)); 02981 02982 while (_is_valid (spineLeftP->rightP)) 02983 spineLeftP = spineLeftP->rightP; 02984 02985 leftTree.endNode.parentP = spineLeftP; 02986 spineLeftP->rightP = &(leftTree.endNode); 02987 02988 // Fix the properties of the right tree: We know its maximal node is the 02989 // same as the current maximum. 02990 rightTree.endNode.parentP = endNode.parentP; 02991 rightTree.endNode.parentP->rightP = &(rightTree.endNode); 02992 02993 // We still have to insert the split node as the minimum node of the right 02994 // tree (we can traverse its leftmost path to find its parent). 02995 if (rightTree.rootP != NULL) 02996 { 02997 while (_is_valid (spineRightP->leftP)) 02998 spineRightP = spineRightP->leftP; 02999 03000 nodeP->parentP = spineRightP; 03001 nodeP->color = Node::RED; 03002 nodeP->rightP = NULL; 03003 nodeP->leftP = NULL; 03004 03005 spineRightP->leftP = nodeP; 03006 03007 // Perform a fixup on the right tree, following the insertion of the 03008 // leftmost node. 03009 rightTree._insert_fixup (nodeP); 03010 } 03011 else 03012 { 03013 // nodeP is the only node in the right tree. 03014 rightTree.rootP = nodeP; 03015 rightTree.iBlackHeight = 1; 03016 03017 nodeP->parentP = NULL; 03018 nodeP->color = Node::BLACK; 03019 nodeP->rightP = NULL; 03020 nodeP->leftP = NULL; 03021 03022 // In this case we also know the tree sizes: 03023 leftTree.iSize = iSize - 1; 03024 rightTree.iSize = 1; 03025 } 03026 03027 // Set nodeP as the minimal node is the right tree. 03028 rightTree.beginNode.parentP = nodeP; 03029 nodeP->leftP = &(rightTree.beginNode); 03030 03031 // Assign leftTree to (*this) and rightTree to the output tree. 03032 _shallow_assign (leftTree); 03033 03034 tree.clear(); 03035 tree._shallow_assign (rightTree); 03036 03037 return; 03038 } 03039 03040 //--------------------------------------------------------- 03041 // Move the contents of one tree to another without actually duplicating 03042 // the nodes. This operation also clears the copied tree. 03043 // 03044 template <class Type, class Compare, typename Allocator> 03045 void Multiset<Type, Compare, Allocator>::_shallow_assign (Self& tree) 03046 { 03047 // Copy the assigned tree properties. 03048 rootP = tree.rootP; 03049 iSize = tree.iSize; 03050 iBlackHeight = tree.iBlackHeight; 03051 03052 // Properly mark the minimal and maximal tree nodes. 03053 beginNode.parentP = tree.beginNode.parentP; 03054 03055 if (beginNode.parentP != NULL) 03056 beginNode.parentP->leftP = &beginNode; 03057 03058 endNode.parentP = tree.endNode.parentP; 03059 03060 if (endNode.parentP != NULL) 03061 endNode.parentP->rightP = &endNode; 03062 03063 // Clear the other tree (without actually deallocating the nodes). 03064 tree._shallow_clear(); 03065 03066 return; 03067 } 03068 03069 //--------------------------------------------------------- 03070 // Clear the properties of the tree, without actually deallocating its nodes. 03071 // 03072 template <class Type, class Compare, typename Allocator> 03073 void Multiset<Type, Compare, Allocator>::_shallow_clear () 03074 { 03075 rootP = NULL; 03076 iSize = 0; 03077 iBlackHeight = 0; 03078 beginNode.parentP = NULL; 03079 endNode.parentP = NULL; 03080 03081 return; 03082 } 03083 03084 //--------------------------------------------------------- 03085 // Remove the given tree node. 03086 // 03087 template <class Type, class Compare, typename Allocator> 03088 void Multiset<Type, Compare, Allocator>::_remove_at (Node* nodeP) 03089 { 03090 CGAL_multiset_precondition (_is_valid (nodeP)); 03091 03092 if (nodeP == rootP && 03093 ! _is_valid (rootP->leftP) && ! _is_valid (rootP->rightP)) 03094 { 03095 // In case of deleting the single object stored in the tree, free the root, 03096 // thus emptying the tree. 03097 _deallocate_node (rootP); 03098 03099 rootP = NULL; 03100 beginNode.parentP = NULL; 03101 endNode.parentP = NULL; 03102 iSize = 0; 03103 iBlackHeight = 0; 03104 03105 return; 03106 } 03107 03108 // Remove the given node from the tree. 03109 if (_is_valid (nodeP->leftP) && _is_valid (nodeP->rightP)) 03110 { 03111 // If the node we want to remove has two children, find its successor, 03112 // which is the leftmost child in its right sub-tree and has at most 03113 // one child (it may have a right child). 03114 Node *succP = _sub_minimum (nodeP->rightP); 03115 CGAL_multiset_assertion (_is_valid (succP)); 03116 03117 // Now physically swap nodeP and its successor. Notice this may temporarily 03118 // violate the tree properties, but we are going to remove nodeP anyway. 03119 // This way we have moved nodeP to a position were it is more convinient 03120 // to delete it. 03121 _swap (nodeP, succP); 03122 } 03123 03124 // At this stage, the node we are going to remove has at most one child. 03125 Node *childP = NULL; 03126 03127 if (_is_valid (nodeP->leftP)) 03128 { 03129 CGAL_multiset_assertion (! _is_valid (nodeP->rightP)); 03130 childP = nodeP->leftP; 03131 } 03132 else 03133 { 03134 childP = nodeP->rightP; 03135 } 03136 03137 // Splice out the node to be removed, by linking its parent straight to the 03138 // removed node's single child. 03139 if (_is_valid (childP)) 03140 childP->parentP = nodeP->parentP; 03141 03142 if (nodeP->parentP == NULL) 03143 { 03144 // If we are deleting the root, make the child the new tree node. 03145 rootP = childP; 03146 03147 // If the deleted root is black, decrement the black height of the tree. 03148 if (nodeP->color == Node::BLACK) 03149 iBlackHeight--; 03150 } 03151 else 03152 { 03153 // Link the removed node parent to its child. 03154 if (nodeP == nodeP->parentP->leftP) 03155 { 03156 nodeP->parentP->leftP = childP; 03157 } 03158 else 03159 { 03160 nodeP->parentP->rightP = childP; 03161 } 03162 } 03163 03164 // Fix-up the red-black properties that may have been damaged: If we have 03165 // just removed a black node, the black-height property is no longer valid. 03166 if (nodeP->color == Node::BLACK) 03167 _remove_fixup (childP, nodeP->parentP); 03168 03169 // In case we delete the tree minimum of maximum, update the relevant 03170 // pointers. 03171 if (nodeP == beginNode.parentP) 03172 { 03173 beginNode.parentP = nodeP->successor(); 03174 03175 if (_is_valid (beginNode.parentP)) 03176 beginNode.parentP->leftP = &beginNode; 03177 else 03178 beginNode.parentP = NULL; 03179 } 03180 else if (nodeP == endNode.parentP) 03181 { 03182 endNode.parentP = nodeP->predecessor(); 03183 03184 if (_is_valid (endNode.parentP)) 03185 endNode.parentP->rightP = &endNode; 03186 else 03187 endNode.parentP = NULL; 03188 } 03189 03190 // Delete the unnecessary node. 03191 _deallocate_node (nodeP); 03192 03193 // Decrement the number of objects in the tree. 03194 if (iSize > 0) 03195 iSize--; 03196 03197 return; 03198 } 03199 03200 //--------------------------------------------------------- 03201 // Swap the location two nodes in the tree. 03202 // 03203 template <class Type, class Compare, typename Allocator> 03204 void Multiset<Type, Compare, Allocator>::_swap (Node* node1_P, 03205 Node* node2_P) 03206 { 03207 CGAL_multiset_assertion (_is_valid (node1_P)); 03208 CGAL_multiset_assertion (_is_valid (node2_P)); 03209 03210 // Store the properties of the first node. 03211 typename Node::Node_color color1 = node1_P->color; 03212 Node *parent1_P = node1_P->parentP; 03213 Node *right1_P = node1_P->rightP; 03214 Node *left1_P = node1_P->leftP; 03215 03216 // Copy the properties of the second node to the first node. 03217 node1_P->color = node2_P->color; 03218 03219 if (node1_P != node2_P->parentP) 03220 { 03221 if (node2_P->parentP == NULL) 03222 { 03223 rootP = node1_P; 03224 } 03225 else 03226 { 03227 if (node2_P->parentP->leftP == node2_P) 03228 node2_P->parentP->leftP = node1_P; 03229 else 03230 node2_P->parentP->rightP = node1_P; 03231 } 03232 03233 node1_P->parentP = node2_P->parentP; 03234 } 03235 else 03236 { 03237 node1_P->parentP = node2_P; 03238 } 03239 03240 if (node1_P != node2_P->rightP) 03241 { 03242 if (_is_valid (node2_P->rightP)) 03243 node2_P->rightP->parentP = node1_P; 03244 03245 node1_P->rightP = node2_P->rightP; 03246 } 03247 else 03248 { 03249 node1_P->rightP = node2_P; 03250 } 03251 03252 if (node1_P != node2_P->leftP) 03253 { 03254 if (_is_valid (node2_P->leftP)) 03255 node2_P->leftP->parentP = node1_P; 03256 03257 node1_P->leftP = node2_P->leftP; 03258 } 03259 else 03260 { 03261 node1_P->leftP = node2_P; 03262 } 03263 03264 // Copy the stored properties of the first node to the second node. 03265 node2_P->color = color1; 03266 03267 if (node2_P != parent1_P) 03268 { 03269 if (parent1_P == NULL) 03270 { 03271 rootP = node2_P; 03272 } 03273 else 03274 { 03275 if (parent1_P->leftP == node1_P) 03276 parent1_P->leftP = node2_P; 03277 else 03278 parent1_P->rightP = node2_P; 03279 } 03280 03281 node2_P->parentP = parent1_P; 03282 } 03283 else 03284 { 03285 node2_P->parentP = node1_P; 03286 } 03287 03288 if (node2_P != right1_P) 03289 { 03290 if (_is_valid (right1_P)) 03291 right1_P->parentP = node2_P; 03292 03293 node2_P->rightP = right1_P; 03294 } 03295 else 03296 { 03297 node2_P->rightP = node1_P; 03298 } 03299 03300 if (node2_P != left1_P) 03301 { 03302 if (_is_valid (left1_P)) 03303 left1_P->parentP = node2_P; 03304 03305 node2_P->leftP = left1_P; 03306 } 03307 else 03308 { 03309 node2_P->leftP = node1_P; 03310 } 03311 03312 // If one of the swapped nodes used to be the tree minimum, update 03313 // the properties of the fictitious before-the-begin node. 03314 if (beginNode.parentP == node1_P) 03315 { 03316 beginNode.parentP = node2_P; 03317 node2_P->leftP = &beginNode; 03318 } 03319 else if (beginNode.parentP == node2_P) 03320 { 03321 beginNode.parentP = node1_P; 03322 node1_P->leftP = &beginNode; 03323 } 03324 03325 // If one of the swapped nodes used to be the tree maximum, update 03326 // the properties of the fictitious past-the-end node. 03327 if (endNode.parentP == node1_P) 03328 { 03329 endNode.parentP = node2_P; 03330 node2_P->rightP = &endNode; 03331 } 03332 else if (endNode.parentP == node2_P) 03333 { 03334 endNode.parentP = node1_P; 03335 node1_P->rightP = &endNode; 03336 } 03337 03338 return; 03339 } 03340 03341 //--------------------------------------------------------- 03342 // Swap the location two sibling nodes in the tree. 03343 // 03344 template <class Type, class Compare, typename Allocator> 03345 void Multiset<Type, Compare, Allocator>::_swap_siblings (Node* node1_P, 03346 Node* node2_P) 03347 { 03348 CGAL_multiset_assertion (_is_valid (node1_P)); 03349 CGAL_multiset_assertion (_is_valid (node2_P)); 03350 03351 // Store the properties of the first node. 03352 typename Node::Node_color color1 = node1_P->color; 03353 Node *right1_P = node1_P->rightP; 03354 Node *left1_P = node1_P->leftP; 03355 03356 // Copy the properties of the second node to the first node. 03357 node1_P->color = node2_P->color; 03358 03359 node1_P->rightP = node2_P->rightP; 03360 if (_is_valid (node1_P->rightP)) 03361 node1_P->rightP->parentP = node1_P; 03362 03363 node1_P->leftP = node2_P->leftP; 03364 if (_is_valid (node1_P->leftP)) 03365 node1_P->leftP->parentP = node1_P; 03366 03367 // Copy the stored properties of the first node to the second node. 03368 node2_P->color = color1; 03369 03370 node2_P->rightP = right1_P; 03371 if (_is_valid (node2_P->rightP)) 03372 node2_P->rightP->parentP = node2_P; 03373 03374 node2_P->leftP = left1_P; 03375 if (_is_valid (node2_P->leftP)) 03376 node2_P->leftP->parentP = node2_P; 03377 03378 // Swap the children of the common parent node. 03379 Node *parent_P = node1_P->parentP; 03380 Node *temp; 03381 03382 CGAL_multiset_assertion (parent_P == node2_P->parentP); 03383 03384 temp = parent_P->leftP; 03385 parent_P->leftP = parent_P->rightP; 03386 parent_P->rightP = temp; 03387 03388 // If one of the swapped nodes used to be the tree minimum, update 03389 // the properties of the fictitious before-the-begin node. 03390 if (beginNode.parentP == node1_P) 03391 { 03392 beginNode.parentP = node2_P; 03393 node2_P->leftP = &beginNode; 03394 } 03395 else if (beginNode.parentP == node2_P) 03396 { 03397 beginNode.parentP = node1_P; 03398 node1_P->leftP = &beginNode; 03399 } 03400 03401 // If one of the swapped nodes used to be the tree maximum, update 03402 // the properties of the fictitious past-the-end node. 03403 if (endNode.parentP == node1_P) 03404 { 03405 endNode.parentP = node2_P; 03406 node2_P->rightP = &endNode; 03407 } 03408 else if (endNode.parentP == node2_P) 03409 { 03410 endNode.parentP = node1_P; 03411 node1_P->rightP = &endNode; 03412 } 03413 03414 return; 03415 } 03416 03417 //--------------------------------------------------------- 03418 // Calculate the height of the subtree spanned by a given node. 03419 // 03420 template <class Type, class Compare, typename Allocator> 03421 size_t Multiset<Type, Compare, Allocator>::_sub_height 03422 (const Node* nodeP) const 03423 { 03424 CGAL_multiset_assertion (_is_valid (nodeP)); 03425 03426 // Recursively calculate the heights of the left and right sub-trees. 03427 size_t iRightHeight = 0; 03428 size_t iLeftHeight = 0; 03429 03430 if (_is_valid (nodeP->rightP)) 03431 iRightHeight = _sub_height (nodeP->rightP); 03432 03433 if (_is_valid (nodeP->leftP)) 03434 iLeftHeight = _sub_height (nodeP->leftP); 03435 03436 // Return the maximal child sub-height + 1 (the current node). 03437 return ((iRightHeight > iLeftHeight) ? (iRightHeight + 1) : 03438 (iLeftHeight + 1)); 03439 } 03440 03441 //--------------------------------------------------------- 03442 // Calculate the height of the subtree spanned by a given node. 03443 // 03444 template <class Type, class Compare, typename Allocator> 03445 bool Multiset<Type, Compare, Allocator>::_sub_is_valid 03446 (const Node* nodeP, 03447 size_t& sub_size, 03448 size_t& sub_bh) const 03449 { 03450 // Make sure that the node is valid. 03451 if (! _is_valid (nodeP)) 03452 return (false); 03453 03454 // If the node is red, make sure that both it children are black (note that 03455 // NULL nodes are also considered to be black). 03456 if (_is_red (nodeP) && 03457 (! _is_black (nodeP->rightP) || ! _is_black (nodeP->leftP))) 03458 { 03459 return (false); 03460 } 03461 03462 // Recursively calculate the black heights of the left and right sub-trees. 03463 size_t iBlack = ((nodeP->color == Node::BLACK) ? 1 : 0); 03464 size_t iLeftSize = 0; 03465 size_t iLeftBHeight = 0; 03466 size_t iRightSize = 0; 03467 size_t iRightBHeight = 0; 03468 03469 if (_is_valid (nodeP->leftP)) 03470 { 03471 // Make sure that the object stored at nodeP is not smaller than the one 03472 // stored at its left child. 03473 if (comp_f (nodeP->object, nodeP->leftP->object) == SMALLER) 03474 return (false); 03475 03476 // Recursively check that the left sub-tree is valid. 03477 if (! _sub_is_valid (nodeP->leftP, iLeftSize, iLeftBHeight)) 03478 return (false); 03479 } 03480 03481 if (_is_valid (nodeP->rightP)) 03482 { 03483 // Make sure that the object stored at nodeP is not larger than the one 03484 // stored at its right child. 03485 if (comp_f (nodeP->object, nodeP->rightP->object) == LARGER) 03486 return (false); 03487 03488 // Recursively check that the right sub-tree is valid. 03489 if (! _sub_is_valid (nodeP->rightP, iRightSize, iRightBHeight)) 03490 return (false); 03491 } 03492 03493 // Compute the size of the entire sub-tree. 03494 sub_size = iRightSize + iLeftSize + 1; 03495 03496 // Make sure that the black heights of both sub-trees are equal. 03497 if (iRightBHeight != iLeftBHeight) 03498 return (false); 03499 sub_bh = iRightBHeight + iBlack; 03500 03501 // If we reached here, the subtree is valid. 03502 return (true); 03503 } 03504 03505 //--------------------------------------------------------- 03506 // Get the leftmost node in the sub-tree spanned by the given node. 03507 // 03508 template <class Type, class Compare, typename Allocator> 03509 typename Multiset<Type, Compare, Allocator>::Node* 03510 Multiset<Type, Compare, Allocator>::_sub_minimum (Node* nodeP) const 03511 { 03512 CGAL_multiset_assertion (_is_valid (nodeP)); 03513 03514 Node *minP = nodeP; 03515 03516 while (_is_valid (minP->leftP)) 03517 minP = minP->leftP; 03518 return (minP); 03519 } 03520 03521 //--------------------------------------------------------- 03522 // Get the rightmost node in the sub-tree spanned by the given node. 03523 // 03524 template <class Type, class Compare, typename Allocator> 03525 typename Multiset<Type, Compare, Allocator>::Node* 03526 Multiset<Type, Compare, Allocator>::_sub_maximum (Node* nodeP) const 03527 { 03528 CGAL_multiset_assertion (_is_valid (nodeP)); 03529 03530 Node *maxP = nodeP; 03531 03532 while (_is_valid (maxP->rightP)) 03533 maxP = maxP->rightP; 03534 return (maxP); 03535 } 03536 03537 //--------------------------------------------------------- 03538 // Left-rotate the sub-tree spanned by the given node: 03539 // 03540 // | RoateRight(y) | 03541 // y --------------> x 03542 // / \ / \ . 03543 // x T3 RoatateLeft(x) T1 y . 03544 // / \ <-------------- / \ . 03545 // T1 T2 T2 T3 03546 // 03547 template <class Type, class Compare, typename Allocator> 03548 void Multiset<Type, Compare, Allocator>::_rotate_left (Node* xNodeP) 03549 { 03550 // Get the right child of the node. 03551 Node *yNodeP = xNodeP->rightP; 03552 03553 CGAL_multiset_assertion (_is_valid (yNodeP)); 03554 03555 // Change its left subtree (T2) to x's right subtree. 03556 xNodeP->rightP = yNodeP->leftP; 03557 03558 // Link T2 to its new parent x. 03559 if (_is_valid (yNodeP->leftP)) 03560 yNodeP->leftP->parentP = xNodeP; 03561 03562 // Assign x's parent to be y's parent. 03563 yNodeP->parentP = xNodeP->parentP; 03564 03565 if (xNodeP->parentP == NULL) 03566 { 03567 // Make y the new tree root. 03568 rootP = yNodeP; 03569 } 03570 else 03571 { 03572 // Assign a pointer to y from x's parent. 03573 if (xNodeP == xNodeP->parentP->leftP) 03574 { 03575 xNodeP->parentP->leftP = yNodeP; 03576 } 03577 else 03578 { 03579 xNodeP->parentP->rightP = yNodeP; 03580 } 03581 } 03582 03583 // Assign x to be y's left child. 03584 yNodeP->leftP = xNodeP; 03585 xNodeP->parentP = yNodeP; 03586 03587 return; 03588 } 03589 03590 //--------------------------------------------------------- 03591 // Right-rotate the sub-tree spanned by the given node. 03592 // 03593 template <class Type, class Compare, typename Allocator> 03594 void Multiset<Type, Compare, Allocator>::_rotate_right (Node* yNodeP) 03595 { 03596 // Get the left child of the node. 03597 Node *xNodeP = yNodeP->leftP; 03598 03599 CGAL_multiset_assertion (_is_valid (xNodeP)); 03600 03601 // Change its right subtree (T2) to y's left subtree. 03602 yNodeP->leftP = xNodeP->rightP; 03603 03604 // Link T2 to its new parent y. 03605 if (_is_valid (xNodeP->rightP)) 03606 xNodeP->rightP->parentP = yNodeP; 03607 03608 // Assign y's parent to be x's parent. 03609 xNodeP->parentP = yNodeP->parentP; 03610 03611 if (yNodeP->parentP == NULL) 03612 { 03613 // Make x the new tree root. 03614 rootP = xNodeP; 03615 } 03616 else 03617 { 03618 // Assign a pointer to x from y's parent. 03619 if (yNodeP == yNodeP->parentP->leftP) 03620 { 03621 yNodeP->parentP->leftP = xNodeP; 03622 } 03623 else 03624 { 03625 yNodeP->parentP->rightP = xNodeP; 03626 } 03627 } 03628 03629 // Assign y to be x's right child. 03630 xNodeP->rightP = yNodeP; 03631 yNodeP->parentP = xNodeP; 03632 03633 return; 03634 } 03635 03636 //--------------------------------------------------------- 03637 // Duplicate the entire sub-tree rooted at the given node. 03638 // 03639 template <class Type, class Compare, typename Allocator> 03640 typename Multiset<Type, Compare, Allocator>::Node* 03641 Multiset<Type, Compare, Allocator>::_duplicate (const Node* nodeP) 03642 { 03643 CGAL_multiset_assertion (_is_valid (nodeP)); 03644 03645 // Create a node of the same color, containing the same object. 03646 Node *dupNodeP = _allocate_node(nodeP->object, nodeP->color); 03647 03648 // Duplicate the children recursively. 03649 if (_is_valid (nodeP->rightP)) 03650 { 03651 dupNodeP->rightP = _duplicate (nodeP->rightP); 03652 dupNodeP->rightP->parentP = dupNodeP; 03653 } 03654 03655 if (_is_valid (nodeP->leftP)) 03656 { 03657 dupNodeP->leftP = _duplicate (nodeP->leftP); 03658 dupNodeP->leftP->parentP = dupNodeP; 03659 } 03660 03661 // Return the duplicated node. 03662 return (dupNodeP); 03663 } 03664 03665 //--------------------------------------------------------- 03666 // Destroy the entire sub-tree rooted at the given node. 03667 // 03668 template <class Type, class Compare, typename Allocator> 03669 void Multiset<Type, Compare, Allocator>::_destroy (Node* nodeP) 03670 { 03671 CGAL_multiset_assertion (_is_valid (nodeP)); 03672 03673 // Destroy the children recursively. 03674 if (_is_valid (nodeP->rightP)) 03675 _destroy (nodeP->rightP); 03676 nodeP->rightP = NULL; 03677 03678 if (_is_valid (nodeP->leftP)) 03679 _destroy (nodeP->leftP); 03680 nodeP->leftP = NULL; 03681 03682 // Free the subtree root node. 03683 _deallocate_node (nodeP); 03684 03685 return; 03686 } 03687 03688 //--------------------------------------------------------- 03689 // Fix-up the tree so it maintains the red-black properties after insertion. 03690 // 03691 template <class Type, class Compare, typename Allocator> 03692 void Multiset<Type, Compare, Allocator>::_insert_fixup (Node* nodeP) 03693 { 03694 CGAL_multiset_precondition (_is_red (nodeP)); 03695 03696 // Fix the red-black propreties: we may have inserted a red leaf as the 03697 // child of a red parent - so we have to fix the coloring of the parent 03698 // recursively. 03699 Node *currP = nodeP; 03700 Node *grandparentP; 03701 Node *uncleP; 03702 03703 while (currP != rootP && _is_red (currP->parentP)) 03704 { 03705 // Get a pointer to the current node's grandparent (notice the root is 03706 // always black, so the red parent must have a parent). 03707 grandparentP = currP->parentP->parentP; 03708 CGAL_multiset_precondition (grandparentP != NULL); 03709 03710 if (currP->parentP == grandparentP->leftP) 03711 { 03712 // If the red parent is a left child, the uncle is the right child of 03713 // the grandparent. 03714 uncleP = grandparentP->rightP; 03715 03716 if (_is_red (uncleP)) 03717 { 03718 // If both parent and uncle are red, color them black and color the 03719 // grandparent red. 03720 // In case of a NULL uncle, we treat it as a black node. 03721 currP->parentP->color = Node::BLACK; 03722 uncleP->color = Node::BLACK; 03723 grandparentP->color = Node::RED; 03724 03725 // Move to the grandparent. 03726 currP = grandparentP; 03727 } 03728 else 03729 { 03730 // Make sure the current node is a left child. If not, left-rotate 03731 // the parent's sub-tree so the parent becomes the left child of the 03732 // current node (see _rotate_left). 03733 if (currP == currP->parentP->rightP) 03734 { 03735 currP = currP->parentP; 03736 _rotate_left (currP); 03737 } 03738 03739 // Color the parent black and the grandparent red. 03740 currP->parentP->color = Node::BLACK; 03741 CGAL_multiset_assertion (grandparentP == currP->parentP->parentP); 03742 grandparentP->color = Node::RED; 03743 03744 // Right-rotate the grandparent's sub-tree 03745 _rotate_right (grandparentP); 03746 } 03747 } 03748 else 03749 { 03750 // If the red parent is a right child, the uncle is the left child of 03751 // the grandparent. 03752 uncleP = grandparentP->leftP; 03753 03754 if (_is_red (uncleP)) 03755 { 03756 // If both parent and uncle are red, color them black and color the 03757 // grandparent red. 03758 // In case of a NULL uncle, we treat it as a black node. 03759 currP->parentP->color = Node::BLACK; 03760 uncleP->color = Node::BLACK; 03761 grandparentP->color = Node::RED; 03762 03763 // Move to the grandparent. 03764 currP = grandparentP; 03765 } 03766 else 03767 { 03768 // Make sure the current node is a right child. If not, right-rotate 03769 // the parent's sub-tree so the parent becomes the right child of the 03770 // current node. 03771 if (currP == currP->parentP->leftP) 03772 { 03773 currP = currP->parentP; 03774 _rotate_right (currP); 03775 } 03776 03777 // Color the parent black and the grandparent red. 03778 currP->parentP->color = Node::BLACK; 03779 CGAL_multiset_assertion(grandparentP == currP->parentP->parentP); 03780 grandparentP->color = Node::RED; 03781 03782 // Left-rotate the grandparent's sub-tree 03783 _rotate_left (grandparentP); 03784 } 03785 } 03786 } 03787 03788 // Make sure that the root is black. 03789 if (_is_red (rootP)) 03790 { 03791 // In case we color a red root black, we should increment the black 03792 // height of the tree. 03793 rootP->color = Node::BLACK; 03794 iBlackHeight++; 03795 } 03796 03797 return; 03798 } 03799 03800 //--------------------------------------------------------- 03801 // Fix-up the tree so it maintains the red-black properties after removal. 03802 // 03803 template <class Type, class Compare, typename Allocator> 03804 void Multiset<Type, Compare, Allocator>::_remove_fixup (Node* nodeP, 03805 Node* parentP) 03806 { 03807 Node *currP = nodeP; 03808 Node *currParentP = parentP; 03809 Node *siblingP; 03810 03811 while (currP != rootP && _is_black (currP)) 03812 { 03813 // Get a pointer to the current node's sibling (notice that the node's 03814 // parent must exist, since the node is not the rootP). 03815 if (currP == currParentP->leftP) 03816 { 03817 // If the current node is a left child, its sibling is the right 03818 // child of the parent. 03819 siblingP = currParentP->rightP; 03820 03821 // Check the sibling's color. Notice that NULL nodes are treated 03822 // as if they are colored black. 03823 if (_is_red (siblingP)) 03824 { 03825 // In case the sibling is red, color it black and rotate. 03826 // Then color the parent red (and the grandparent is now black). 03827 siblingP->color = Node::BLACK; 03828 currParentP->color = Node::RED; 03829 _rotate_left (currParentP); 03830 siblingP = currParentP->rightP; 03831 } 03832 03833 CGAL_multiset_assertion (_is_valid (siblingP)); 03834 03835 if (_is_black (siblingP->leftP) && _is_black (siblingP->rightP)) 03836 { 03837 // If the sibling has two black children, color it red. 03838 siblingP->color = Node::RED; 03839 03840 // The black-height of the entire sub-tree rooted at the parent is 03841 // now too small - fix it up recursively. 03842 currP = currParentP; 03843 currParentP = currParentP->parentP; 03844 03845 // In case the current node is the tree root, we have just decreased 03846 // the black height of the entire tree. 03847 if (currP == rootP) 03848 { 03849 CGAL_multiset_assertion (currParentP == NULL); 03850 iBlackHeight--; 03851 } 03852 } 03853 else 03854 { 03855 // In this case, at least one of the sibling's children is red. 03856 // It is therfore obvious that the sibling itself is black. 03857 if (_is_black (siblingP->rightP)) 03858 { 03859 // The left child is red: Color it black, and color the sibling red. 03860 siblingP->leftP->color = Node::BLACK; 03861 siblingP->color = Node::RED; 03862 03863 _rotate_right (siblingP); 03864 siblingP = currParentP->rightP; 03865 } 03866 03867 // Color the parent black (it is now safe to color the sibling with 03868 // the same color the parent used to have) and rotate left around it. 03869 siblingP->color = currParentP->color; 03870 currParentP->color = Node::BLACK; 03871 if (_is_valid (siblingP->rightP)) 03872 siblingP->rightP->color = Node::BLACK; 03873 _rotate_left (currParentP); 03874 03875 // We set currP to be the root node in order to terminate the loop. 03876 currP = rootP; 03877 } 03878 } 03879 else 03880 { 03881 // If the current node is a right child, its sibling is the left 03882 // child of the parent. 03883 siblingP = currParentP->leftP; 03884 03885 // Check the sibling's color. Notice that NULL nodes are treated 03886 // as if they are colored black. 03887 if (_is_red (siblingP)) 03888 { 03889 // In case the sibling is red, color it black and rotate. 03890 // Then color the parent red (and the grandparent is now black). 03891 siblingP->color = Node::BLACK; 03892 currParentP->color = Node::RED; 03893 _rotate_right (currParentP); 03894 03895 siblingP = currParentP->leftP; 03896 } 03897 03898 CGAL_multiset_assertion (_is_valid (siblingP)); 03899 03900 if (_is_black (siblingP->leftP) && _is_black (siblingP->rightP)) 03901 { 03902 // If the sibling has two black children, color it red. 03903 siblingP->color = Node::RED; 03904 03905 // The black-height of the entire sub-tree rooted at the parent is 03906 // now too small - fix it up recursively. 03907 currP = currParentP; 03908 currParentP = currParentP->parentP; 03909 03910 // In case the current node is the tree root, we have just decreased 03911 // the black height of the entire tree. 03912 if (currP == rootP) 03913 { 03914 CGAL_multiset_assertion (currParentP == NULL); 03915 iBlackHeight--; 03916 } 03917 } 03918 else 03919 { 03920 // In this case, at least one of the sibling's children is red. 03921 // It is therfore obvious that the sibling itself is black. 03922 if (_is_black (siblingP->leftP)) 03923 { 03924 // The right child is red: Color it black, and color the sibling red. 03925 siblingP->rightP->color = Node::BLACK; 03926 siblingP->color = Node::RED; 03927 03928 _rotate_left (siblingP); 03929 siblingP = currParentP->leftP; 03930 } 03931 03932 // Color the parent black (it is now safe to color the sibling with 03933 // the same color the parent used to have) and rotate right around it. 03934 siblingP->color = currParentP->color; 03935 currParentP->color = Node::BLACK; 03936 if (_is_valid (siblingP->leftP)) 03937 siblingP->leftP->color = Node::BLACK; 03938 _rotate_right (currParentP); 03939 03940 // We set currP to be the root node in order to terminate the loop. 03941 currP = rootP; 03942 } 03943 } 03944 } 03945 03946 // Make sure the current node is black. 03947 if (_is_red (currP)) 03948 { 03949 currP->color = Node::BLACK; 03950 03951 if (currP == rootP) 03952 { 03953 // In case we color a red root black, we should increment the black 03954 // height of the tree. 03955 iBlackHeight++; 03956 } 03957 } 03958 03959 return; 03960 } 03961 03962 //--------------------------------------------------------- 03963 // Allocate and initialize new tree node. 03964 // 03965 #ifndef CGAL_CFG_OUTOFLINE_MEMBER_DEFINITION_BUG 03966 template <class Type, class Compare, typename Allocator> 03967 typename Multiset<Type, Compare, Allocator>::Node* 03968 Multiset<Type, Compare, Allocator>::_allocate_node 03969 (const Type& object, 03970 typename Node::Node_color color) 03971 { 03972 CGAL_multiset_assertion (color != Node::DUMMY_BEGIN && 03973 color != Node::DUMMY_END); 03974 03975 Node* new_node = node_alloc.allocate(1); 03976 03977 node_alloc.construct(new_node, beginNode); 03978 new_node->init(object, color); 03979 return (new_node); 03980 } 03981 #endif 03982 03983 //--------------------------------------------------------- 03984 // De-allocate a tree node. 03985 // 03986 template <class Type, class Compare, typename Allocator> 03987 void Multiset<Type, Compare, Allocator>::_deallocate_node (Node* nodeP) 03988 { 03989 node_alloc.destroy (nodeP); 03990 node_alloc.deallocate (nodeP, 1); 03991 03992 return; 03993 } 03994 03995 CGAL_END_NAMESPACE 03996 03997 #endif