include/Tree/Avl.hpp

Go to the documentation of this file.
00001 #ifndef hpp_CPP_AVLTree_CPP_hpp
00002 #define hpp_CPP_AVLTree_CPP_hpp
00003 
00004 // Need comparable declaration
00005 #include "Comparable.hpp"
00006 // Need FIFO for iterator
00007 #include "FIFO.hpp"
00008 // We need Bool2Type
00009 #include "Bool2Type.hpp"
00010 
00011 #ifdef _MSC_VER
00012 #pragma warning(push)
00013 #pragma warning(disable: 4251)
00014 #endif 
00015 
00016 #ifdef _MSC_VER
00017 #pragma warning(disable: 4786)
00018 #endif
00019 
00021 namespace Tree
00022 {
00024     namespace AVL
00025     {
00026         using namespace ::Comparator;
00027 
00029         template <typename T, typename KeyType>
00030         struct NoDeletion
00031         {   inline static void deleter(T &, KeyType) {} };
00033         template <typename T, typename KeyType>
00034         struct PointerDeletion
00035         {   inline static void deleter(T & t, KeyType) { delete t; t = 0; } };
00037         template <typename T, typename KeyType>
00038         struct ArrayDeletion
00039         {   inline static void deleter(T & t, KeyType) { delete[] t; t = 0; } };
00040 
00042         struct AllNodes
00043         {
00045             enum Balance { LeftTreeIsHeavier = -1, Balanced = 0, RightTreeIsHeavier = 1 };
00046         };
00047 
00048         template <typename T, typename KeyType, typename DeleterT = NoDeletion<T, KeyType> > 
00049         struct Node : public AllNodes
00050         {
00051         // The direction
00052             enum { Left = 0, Right = 1 };
00053         
00054         // Interface
00056             inline Node*& left() { return child[Left]; } 
00058             inline Node*& right() { return child[Right]; }
00060             inline const Node*& left() const { return child[Left]; } 
00062             inline const Node*& right() const { return child[Right]; }
00063 
00065             inline void left(Node * left) { child[Left] = left; }
00067             inline void right(Node * right) { child[Right] = right; }
00068 
00070             inline Node *& fromCompare(const Comparator::CompareType comp) { return child[comp == Comparator::Greater]; }
00072             inline Node *& fromInverseCompare(const Comparator::CompareType comp) { return child[comp != Comparator::Greater]; }
00073 
00075             static inline const Balance balanceFromCompare(const Comparator::CompareType comp) { return comp == Comparator::Greater ? RightTreeIsHeavier : LeftTreeIsHeavier; }
00077             static inline const Balance balanceFromInverseCompare(const Comparator::CompareType comp) { return comp != Comparator::Greater ? RightTreeIsHeavier : LeftTreeIsHeavier; }
00079             static inline const Balance strictBalanceFromCompare(const Comparator::CompareType comp) { return comp == Comparator::Greater ? RightTreeIsHeavier : (comp == Comparator::Equal ? Balanced : LeftTreeIsHeavier); }
00080 
00081         // Constructor
00082             inline Node( Node* _root, const T& _data, KeyType _key) : rootNode(_root), data(_data), key(_key), balance(Balanced) { child[Left] = child[Right] = 0; } 
00083             inline ~Node() {  DeleterT::deleter(data, key); }
00084 
00085         // Members
00087             Balance                                             balance;
00089             Node*                                               child[2];
00091             Node*                                               rootNode;
00093             T                                                   data;
00095             KeyType                                             key;
00096         };
00097 
00098 
00099 
00100 
00102         template <typename T, typename KeyType, typename DeleterT = NoDeletion<T, KeyType> > 
00103         class Iterator
00104         {
00105         public:
00106             typedef Node<T, KeyType, DeleterT>  NodeT;
00107 
00108         public:
00110             mutable NodeT *             node;
00111 
00112         public:
00114             inline Iterator( NodeT* _node = NULL ) : node(_node)
00115             {   if(node != NULL )
00116                 {   if( node->left() != NULL) nodes.Push( node->left() );
00117                     if( node->right()!= NULL) nodes.Push( node->right()); }
00118             }
00119 
00121             inline Iterator( const Iterator& iter ) : node(iter.node), nodes(iter.nodes) {}             
00122 
00123             // Operators
00124         public:
00126             inline T& operator *()                  { return  node->data; }
00128             inline const T& operator *() const      { return  node->data; }
00130 //          inline T* operator ->()                 { return node->data; } 
00132 //          inline const T* operator ->() const     { return node->data; } 
00133 
00135             inline void Mutate(const T & newData)   { node->data = newData; }
00136             
00138             inline Iterator& operator ++() const
00139             {   if (nodes.getSize())
00140                 {
00141                     node = nodes.Pop();
00142                     if( node->left() ) nodes.Push( node->left() );
00143                     if( node->right()) nodes.Push( node->right());
00144                 }
00145                 else node = 0;
00146                 return *const_cast<Iterator*>( this );
00147             }
00148 
00150             inline Iterator operator ++(int) const                  { Iterator tmp(*this); ++(*this); return tmp; }
00152             inline bool operator ==( const Iterator& rhs ) const    { return(node==rhs.node); }
00154             inline bool operator !=( const Iterator& rhs ) const    { return(node!=rhs.node); }
00155 
00157             inline Iterator& operator = ( const Iterator& iter ) const { node = iter.node; nodes = iter.nodes; return *const_cast< Iterator* >(this); }
00158 
00160             inline bool isValid() const { return node != NULL; }
00161 
00164             inline Iterator getLeftIterator() const { return Iterator( node != NULL ? node->left() : NULL ); }
00167             inline Iterator getRightIterator() const { return Iterator( node != NULL ? node->right() : NULL ); }
00170             inline Iterator getParentIterator() const { return Iterator( node != NULL ? node->rootNode : NULL ); }
00172             inline bool isTerminal() const { return node != NULL && node->left() == NULL && node->right() == NULL; }
00175             inline const KeyType * getKey() const { if (node) return &node->key; return 0; } 
00176 
00177         private:
00179             mutable Stack::PlainOldData::FIFO< NodeT* >   nodes;
00180         };
00181 
00182 
00184         typedef Bool2Type<true>     LeftSide;
00185         typedef Bool2Type<false>    RightSide;
00186 
00187 
00189         template <bool bLeft>       struct selectBalance { enum { Result = AllNodes::LeftTreeIsHeavier }; };
00190         template <>                 struct selectBalance<false> { enum { Result = AllNodes::RightTreeIsHeavier }; };
00191         template <bool bLeft>       struct invSelectBalance { enum { Result = AllNodes::RightTreeIsHeavier }; };
00192         template <>                 struct invSelectBalance<false> { enum { Result = AllNodes::LeftTreeIsHeavier }; };
00193 
00194 
00196         template < typename T, typename KeyType, class Policy = Comparator::DefaultComparator, typename DeleterT = NoDeletion<T, KeyType> > 
00197         class Tree
00198         {   
00199             // Members
00200         private:
00201             typedef Node<T, KeyType, DeleterT>              NodeT;
00202             typedef typename NodeT::Balance                     ResultT;
00203             typedef ::Comparator::Comparable<KeyType, Policy>   CompareT;
00204 
00206             NodeT *     root;
00208             uint32      size;
00209 
00210         private:
00212             enum OperationResult { Ok = 1, NeedReBalancing = 0, Invalid = -1 };
00213             
00214         protected:
00216             enum { NoRelativeParent =  NULL, };
00217 
00218             // Interface which still keep the tree balanced
00219         public:
00221             typedef Iterator<T, KeyType, DeleterT>      IterT;
00222 
00228             inline bool insertObject( const T& obj, KeyType key)
00229             {
00231                 if (insertInTree(&root, obj, key) == Invalid) return false;
00232                 size++; return true;
00233             }
00234 
00238             inline bool Delete( KeyType key )
00239             {
00240                 return deleteInTree(&root, key) != Invalid;
00241             }
00242 
00245             inline bool Delete( const IterT & iter )
00246             {
00247                 // Check invariant 
00248                 if(!iter.isValid()) return false;
00249 
00250                 // Suppose it is going to work
00251                 OperationResult result = Ok;
00252 
00253                 // If we are working with the root node, then handle the case correctly
00254                 if (iter.node->rootNode == NULL || iter.node->rootNode->rootNode == NULL)
00255                 {   // We can use the other function for this (as the search will directly give the correct result)
00256                     return deleteInTree(&root, iter.node->key) != Invalid;
00257                 }
00258                 // Else perform the search from the root itself
00259                 else 
00260                 {
00261                     // We need to walk up the tree until we find a parent whose balance is Balanced
00262                     NodeT * current = iter.node->rootNode->rootNode;
00263                     while (current && current->balance != AllNodes::Balanced)
00264                     {   // Simply go up
00265                         current = current->rootNode;
00266                     }
00267                     // Not found, so call the other algorithm to sort this out
00268                     if (!current || !current->rootNode) return deleteInTree(&root, iter.node->key) != Invalid;
00269                     
00270                     // Need to find the right root node address then
00271                     NodeT ** newRoot = current->rootNode->left() == current ? &current->rootNode->left() : &current->rootNode->right();
00272                     return deleteInTree(newRoot, iter.node->key) != Invalid;
00273                 }
00274             }
00275 
00277             inline void Clear()
00278             {
00279                 if (root)   deleteTree(root);
00280                 root = 0; size = 0;
00281             }
00282 
00285             inline bool checkTree()
00286             {
00287                 return checkTree(root);
00288             }
00289             inline bool checkTree(NodeT * node)
00290             {
00291                 if (!node) return true;
00292                 CompareT        key(node->key);
00293                 if (node->left() && node->left()->rootNode != node && key.Compare(node->left()->key) != Comparator::Less) 
00294                     return false; 
00295                 if (node->right() && node->right()->rootNode != node && key.Compare(node->left()->key) != Comparator::Greater) 
00296                     return false;
00297                 if (!node->right() && !node->left())
00298                 {
00299                     if (node->balance != AllNodes::Balanced)
00300                         return false;
00301                 } else
00302                 {
00303                     if (!node->right() && node->balance != AllNodes::LeftTreeIsHeavier)
00304                         return false;
00305                     if (!node->left() && node->balance != AllNodes::RightTreeIsHeavier)
00306                         return false;
00307                 }
00308                 return checkTree(node->left()) && checkTree(node->right());
00309             }
00310 
00311             // Construction and destruction
00312         public:
00314             Tree() : root(NULL), size(0) {}
00316             virtual ~Tree() { Clear(); }
00317             
00318             // Helpers functions
00319         private:
00330             NodeT * rotate2(NodeT ** parent, typename CompareT::Result result)
00331             {
00332                 NodeT *B, *C, *D, *E;
00333                 NodeT *Bparent = (*parent)->rootNode;
00334                 B = *parent;
00335                 if (result == Comparator::Greater)
00336                 {
00337                     D = B->right();
00338                     C = D->left();
00339                     E = D->right();
00340 
00341                     *parent = D;
00342                 
00343                     D->left(B);
00344                     B->right(C);
00345                 } else
00346                 {
00347                     D = B->left();
00348                     C = D->right();
00349                     E = D->left();
00350 
00351                     *parent = D;
00352                 
00353                     D->right(B);
00354                     B->left(C);
00355                 }
00356                 // Fix the parent nodes
00357                 if (C) C->rootNode = B;
00358                 B->rootNode = D;
00359                 D->rootNode = Bparent;
00360                 B->balance = AllNodes::Balanced;
00361                 D->balance = AllNodes::Balanced;
00362                 return E;
00363             }
00364 
00381             NodeT * rotate3(NodeT ** parent, typename CompareT::Result result, AllNodes::Balance third)
00382             {
00383                 NodeT *B, *F, *D, *C, *E;
00384                 NodeT *Bparent = (*parent)->rootNode;
00385                 B = *parent;
00386 
00387                 if (result == Comparator::Greater)
00388                 {
00389                     F = B->right();
00390                     D = F->left();
00391                     C = D->left();
00392                     E = D->right();
00393 
00394                     *parent = D;
00395                 
00396                     D->left(B);
00397                     D->right(F);
00398                     B->right(C);
00399                     F->left(E);
00400                 } else
00401                 {
00402                     F = B->left();
00403                     D = F->right();
00404                     C = D->right();
00405                     E = D->left();
00406 
00407                     *parent = D;
00408                 
00409                     D->right(B);
00410                     D->left(F);
00411                     B->left(C);
00412                     F->right(E);
00413                 }
00414 
00415                 // Fix the parent nodes
00416                 if (F) F->rootNode = D;
00417                 if (C) C->rootNode = B;
00418                 if (E) E->rootNode = F; 
00419                 B->rootNode = D;
00420                 D->rootNode = Bparent;
00421 
00422                 D->balance = B->balance = F->balance = AllNodes::Balanced;
00423 
00424                 if (third == AllNodes::Balanced) return 0;
00425                 else if (third == D->balanceFromCompare(result)) 
00426                 {
00427                     /* E holds the insertion so B is unbalanced */ 
00428                     B->balance = B->balanceFromInverseCompare(result);
00429                     return E;
00430                 } else 
00431                 {
00432                     /* C holds the insertion so F is unbalanced */
00433                     F->balance = F->balanceFromCompare(result);
00434                     return C;
00435                 }
00436             }            
00437 
00439             OperationResult rebalancePath(NodeT* current, CompareT & keyToCheck)
00440             {
00441                 typename CompareT::Result result = current ? keyToCheck.Compare(current->key) : Comparator::Equal;
00442                 while (current && result != Comparator::Equal)
00443                 {
00444                     current->balance = current->balanceFromCompare(result);
00445                     current = current->fromCompare(result);
00446                     result = keyToCheck.Compare(current->key);
00447                 }
00448                 return Ok;
00449             }
00450 
00451 
00453             OperationResult rebalanceAfterInsert(NodeT** parent, CompareT & keyToCheck)
00454             {
00455                 NodeT * current = *parent;
00456                 typename CompareT::Result first, second;
00457                 if (current->balance != AllNodes::Balanced)
00458                 {
00459                     first = keyToCheck.Compare(current->key);
00460                     NodeT * next = current->fromCompare(first); 
00461                     if (!next) return Invalid;
00462                     second = keyToCheck.Compare(next->key);
00463                     bool biggerFirst = first == Comparator::Greater;
00464                     bool biggerSecond = second == Comparator::Greater;
00465 
00466                     if (current->balance != current->balanceFromCompare(first))
00467                     {   // Follow the shorter path
00468                         current->balance = AllNodes::Balanced;
00469                         current = next;
00470                     }
00471                     else if (biggerFirst == biggerSecond)
00472                     {   // Two point rotate
00473                         current = rotate2(parent, first);
00474                     } else
00475                     {   // Double rotation
00476                         current = next->fromCompare(second);
00477                         AllNodes::Balance third;
00478                         second = keyToCheck.Compare(current->key);
00479                         third = current->strictBalanceFromCompare(second);
00480                         current = rotate3(parent, first, third);
00481                     }
00482                 }
00483                 return rebalancePath(current, keyToCheck);
00484             }
00485 
00487             OperationResult insertInTree( NodeT** parent, const T& obj, KeyType key)
00488             {
00489                 // Let's consider it will succeed 
00490                 OperationResult result = Ok;
00491                 CompareT        keyToCheck(key);
00492 
00493                 // Find where to insert the node
00494                 // A parent node exists, need to select the right subtree
00495                 NodeT * current = *parent;
00496                 NodeT ** balancer = parent;
00497                 NodeT ** previousRoot = parent;
00498                 typename CompareT::Result compareResult = Comparator::Greater;
00499                 while (current && compareResult != Comparator::Equal)
00500                 {
00501                     typename CompareT::Result compareResult = keyToCheck.Compare(current->key);
00502                     if (current->balance != AllNodes::Balanced) balancer = parent;
00503 
00504                     previousRoot = parent;
00505                     parent = &current->fromCompare(compareResult);
00506                     current = *parent;
00507                 }
00508 
00509                 // Already exist, so reject the insert
00510                 if (current) return Invalid;
00511 
00512                 // Create the node
00513                 current = new NodeT(*previousRoot, obj, key);
00514                 *parent = current;
00515 
00516                 return rebalanceAfterInsert(balancer, keyToCheck);
00517             }
00518             
00519             static inline void SwapAndDelete(NodeT ** targetParent, NodeT ** parent, typename CompareT::Result result)
00520             {
00521                 bool same = targetParent == parent;
00522                 
00523                 NodeT * newTarget = *targetParent;
00524                 NodeT * current = *parent;
00525 
00526                 NodeT * rootNode = newTarget->rootNode;
00527                 *targetParent = current;
00528                 int currentOnLeft = -1;
00529                 if (current->rootNode) currentOnLeft = current->rootNode->left() == current;
00530                 *parent = current->fromInverseCompare(result);
00531                 
00532                 current->left(newTarget->left());
00533                 current->right(newTarget->right());
00534                 current->balance = newTarget->balance;
00535                 if (currentOnLeft != -1)
00536                 {
00537                     if (currentOnLeft)
00538                     {
00539                         if (current->rootNode->left()) current->rootNode->left()->rootNode = current->rootNode;
00540                     }
00541                     else if (current->rootNode->right()) current->rootNode->right()->rootNode = current->rootNode;
00542                 }
00543                 current->rootNode = rootNode;
00544                 if (current->left()) current->left()->rootNode = current;
00545                 if (current->right()) current->right()->rootNode = current;
00546                 
00547                 if (same && *parent) (*parent)->rootNode = rootNode;
00548                 delete newTarget;
00549             }
00550 
00552             NodeT** rebalanceAfterDelete(NodeT** parent, CompareT & keyToCheck, NodeT ** targetParent)
00553             {
00554                 NodeT * newTarget = *targetParent;
00555 
00556                 while (1)
00557                 {
00558                     NodeT * current = *parent;
00559                     typename CompareT::Result compareResult = keyToCheck.Compare(current->key);
00560                     NodeT * next = current->fromCompare(compareResult);
00561                     if (!next) break;
00562 
00563                     if (current->balance == AllNodes::Balanced)
00564                         current->balance = current->balanceFromInverseCompare(compareResult);
00565                     else if (current->balance == current->balanceFromCompare(compareResult))
00566                         current->balance = AllNodes::Balanced;
00567                     else
00568                     {
00569                         NodeT * invertNext = current->fromInverseCompare(compareResult);
00570                         typename CompareT::Result invertResult = compareResult == Comparator::Greater ? Comparator::Less : Comparator::Greater;
00571                         if (invertNext->balance == current->balanceFromCompare(compareResult))
00572                         {   
00573                             NodeT * nextInvertNext = invertNext->fromCompare(compareResult);
00574                             rotate3(parent, invertResult, nextInvertNext->balance);
00575                         } else if (invertNext->balance == AllNodes::Balanced)
00576                         {
00577                             rotate2(parent, invertResult);
00578                             current->balance = current->balanceFromInverseCompare(compareResult);
00579                             (*parent)->balance = current->balanceFromCompare(compareResult);
00580                         } else rotate2(parent, invertResult);
00581 
00582                         if (current == newTarget)
00583                             targetParent = &(*parent)->fromCompare(compareResult);
00584                     }
00585 
00586                     parent = &current->fromCompare(compareResult);
00587                 }
00588                 
00589                 return targetParent;
00590             }
00591 
00595             OperationResult deleteInTree( NodeT** parent, KeyType key )
00596             {
00597                 // Check parameters
00598                 if (parent == NULL || *parent == NULL)  return Invalid;
00599 
00600                 CompareT keyToFind(key);
00601                 OperationResult             result = Ok;
00602 
00603                 NodeT * current = *parent;
00604                 NodeT ** targetParent = 0;
00605                 NodeT ** balanced = parent;
00606 
00607                 typename CompareT::Result compareResult = Comparator::Equal;
00608                 while (current)
00609                 {
00610                     compareResult = keyToFind.Compare(current->key);
00611                     if (compareResult == Comparator::Equal)
00612                     {   // Ok, we have found it
00613                         targetParent = parent;
00614                     }
00615                     // Then need to find with node to swap this one (or continue searching)
00616                     NodeT * next = current->fromCompare(compareResult);
00617                     if (!next) break;
00618 
00619                     // Check the balance to determine which node to balance with once deleted
00620                     NodeT * invertNext = current->fromInverseCompare(compareResult);
00621                     if (current->balance == AllNodes::Balanced
00622                         || (current->balance == current->balanceFromInverseCompare(compareResult) && invertNext->balance == AllNodes::Balanced))
00623                         balanced = parent;
00624 
00625                     parent = &current->fromCompare(compareResult);
00626                     current = *parent;
00627                 }
00628 
00629                 // Not found ?
00630                 if (!targetParent) return Invalid;
00631 
00632                 targetParent = rebalanceAfterDelete(balanced, keyToFind, targetParent);
00633                 SwapAndDelete(targetParent, parent, compareResult);
00634                 
00635                 --size;
00636                 return Ok;
00637             }           
00638 
00639 
00641             void deleteTree(NodeT* node)
00642             {
00643                 NodeT * current = node;
00644                 while (current)
00645                 {
00646                     if (current->left()) { current = current->left(); continue; }
00647                     if (current->right()) { current = current->right(); continue; }
00648                     NodeT * previous = current->rootNode;
00649                     delete current;
00650                     if (previous && previous->left() == current) previous->left(0);
00651                     if (previous && previous->right() == current) previous->right(0);
00652                     current = previous;
00653                 }
00654             }
00655 
00657             inline  NodeT** getRootOf(NodeT* node)
00658             {
00659                 // If the node is already root, or the tree as no node
00660                 if (root == NULL || node == NULL || node->rootNode == NULL) return NULL;
00661                 // If the root node of the given node is the tree root node, return our root node
00662                 else if (node->rootNode->rootNode == NULL)  return &root;
00663                 // Else check if the root node is the left node of the root node, and return the left node
00664                 else if (node->rootNode == node->rootNode->rootNode->left())    return &node->rootNode->rootNode->left();
00665                 // Else it is the right node
00666                 return &node->rootNode->rootNode->right();              
00667             }
00668 
00669 
00671             inline NodeT *& selectSide(NodeT * node, LeftSide *)        { return node->left(); }
00672             inline NodeT *& selectSide(NodeT * node, RightSide *)       { return node->right();}
00673             inline NodeT *& invSelectSide(NodeT * node, LeftSide *)     { return node->right();}
00674             inline NodeT *& invSelectSide(NodeT * node, RightSide *)    { return node->left();}
00675 
00677             template <bool bLeft>   inline void rotate(NodeT ** node, Bool2Type<bLeft>* select)
00678             {
00679                 // Check argument
00680                 if (node == NULL) return;
00681                 
00682                 // Rotate right and left (or vice versa)
00683                 NodeT* tmp = *node;
00684                 *node = invSelectSide(tmp, select);
00685                 invSelectSide(tmp, select) = selectSide(*node, select);
00686                 selectSide(*node, select) = tmp;
00687 
00688                 // Rotate root node with left/right node
00689                 (*node)->rootNode = tmp->rootNode;
00690                 tmp->rootNode = *node;
00691                 if (invSelectSide(tmp, select) != NULL) invSelectSide(tmp, select)->rootNode = selectSide(*node, select);                   
00692             }
00693             
00695             template <bool bLeft>   inline OperationResult balanceShrunk(NodeT ** node, Bool2Type<bLeft>* select)
00696             {
00697                 switch( (*node)->balance )
00698                 {
00699                     case selectBalance<bLeft>::Result :
00700                         {   (*node)->balance = NodeT::Balanced;
00701                             return NeedReBalancing; }
00702                     case NodeT::Balanced:
00703                         {   (*node)->balance = (typename NodeT::Balance)invSelectBalance<bLeft>::Result;
00704                             return Ok;  }
00705                     case invSelectBalance<bLeft>::Result:
00706                     {
00707                         switch (invSelectSide(*node, select)->balance)
00708                         {
00709                             case selectBalance<bLeft>::Result:
00710                             {
00711                                 switch (selectSide(invSelectSide(*node, select), select)->balance)
00712                                 {
00713                                     case selectBalance<bLeft>::Result:
00714                                     {
00715                                         (*node)->balance = NodeT::Balanced;
00716                                         invSelectSide(*node, select)->balance = (typename NodeT::Balance)invSelectBalance<bLeft>::Result;
00717                                         break;
00718                                     }
00719 
00720                                     case NodeT::Balanced:
00721                                     {
00722                                         (*node)->balance = NodeT::Balanced;
00723                                         invSelectSide(*node, select)->balance = NodeT::Balanced;
00724                                         break;
00725                                     }
00726 
00727                                     case invSelectBalance<bLeft>::Result:
00728                                     {
00729                                         (*node)->balance = (typename NodeT::Balance)selectBalance<bLeft>::Result;
00730                                         invSelectSide(*node, select)->balance = NodeT::Balanced;
00731                                         break;
00732                                     }
00733                                 }
00734 
00735                                 selectSide(invSelectSide(*node, select), select)->balance = NodeT::Balanced;
00736 
00737                                 // Inverted rotate invoked
00738                                 rotate(&invSelectSide(*node, select), (Bool2Type<!bLeft>*)0);
00739                                 // Normal rotate here
00740                                 rotate(node, select);
00741 
00742                                 return NeedReBalancing;
00743                             }
00744 
00745                             case NodeT::Balanced:
00746                             {
00747                                 (*node)->balance = (typename NodeT::Balance)invSelectBalance<bLeft>::Result;
00748                                 invSelectSide(*node, select)->balance = (typename NodeT::Balance)selectBalance<bLeft>::Result;
00749                                 rotate(node, select);
00750                                 return Ok;
00751                             }
00752 
00753                             case invSelectBalance<bLeft>::Result:
00754                             {
00755                                 (*node)->balance = invSelectSide(*node, select)->balance = NodeT::Balanced;
00756                                 rotate(node, select);
00757                                 return NeedReBalancing;
00758                             }
00759                         }
00760                         break;
00761                     }
00762                 }
00763                 return Invalid;
00764             }
00765 
00767             template <bool bLeft>   inline OperationResult balanceExpanded(NodeT ** node, Bool2Type<bLeft>* select)
00768             {
00769                 switch ((*node)->balance)
00770                 {
00771                     case selectBalance<bLeft>::Result :
00772                         {
00773                             if (selectSide(*node, select)->balance == (typename NodeT::Balance)selectBalance<bLeft>::Result)
00774                                 {   (*node)->balance = selectSide(*node, select)->balance = NodeT::Balanced;
00775                                     // Inverted rotate invoked
00776                                     rotate(node, (Bool2Type<!bLeft>*)0);    }
00777                             else
00778                             {   switch (invSelectSide(selectSide(*node, select), select)->balance)
00779                                 {
00780                                 case selectBalance<bLeft>::Result :
00781                                     {
00782                                         (*node)->balance = (typename NodeT::Balance)invSelectBalance<bLeft>::Result;
00783                                         selectSide(*node, select)->balance = NodeT::Balanced;
00784                                         break;
00785                                     }
00786                                     
00787                                 case NodeT::Balanced:
00788                                     {
00789                                         (*node)->balance = NodeT::Balanced;
00790                                         selectSide(*node, select)->balance = NodeT::Balanced;
00791                                         break;
00792                                     }
00793                                     
00794                                 case invSelectBalance<bLeft>::Result:
00795                                     {
00796                                         (*node)->balance = NodeT::Balanced;
00797                                         selectSide(*node, select)->balance = (typename NodeT::Balance)selectBalance<bLeft>::Result;
00798                                         break;
00799                                     }
00800                                 }
00801                                 
00802                                 invSelectSide(selectSide(*node, select), select)->balance = NodeT::Balanced;
00803                                 
00804                                 // Forward rotate
00805                                 rotate(&selectSide(*node, select), select);
00806                                 // Inverted rotate
00807                                 rotate(node, (Bool2Type<!bLeft>*)0);    
00808                             }
00809                             return Ok;
00810                         }
00811                         
00812                     case NodeT::Balanced:
00813                         {
00814                             (*node)->balance = (typename NodeT::Balance)selectBalance<bLeft>::Result;
00815                             return NeedReBalancing;
00816                         }
00817                         
00818                     case invSelectBalance<bLeft>::Result:
00819                         {
00820                             (*node)->balance = NodeT::Balanced;
00821                             return Ok;
00822                         }
00823                 }
00824                 return Invalid;
00825             }
00826 
00827             template <class U>
00828             void Swap(U & a, U & b)
00829             {
00830                 U tmp = a;
00831                 a = b;
00832                 b = tmp;
00833             }
00834 
00836             inline void SwapNodes(NodeT * & a, NodeT * & b)
00837             {
00838                 // We want to do a = b and b = a
00839                 // First, save the side of a and b compared to their root node
00840                 int aWasLeftOfARoot = a->rootNode ? a->rootNode->left() == a : -1;
00841                 int bWasLeftOfBRoot = b->rootNode ? b->rootNode->left() == b : -1;
00842 
00843                 // This means a.left = b.left and a.right = b.right and a.root = b.root and a.balance = b.balance while (same thing for b)
00844                 NodeT * oldBRight = b->right(), * oldBLeft = b->left(), * oldBRoot = b->rootNode, * tmpNode = b;
00845                 NodeT::Balance oldBBalance = b->balance;
00846 
00847                 // Set swap the pointers
00848                 b->rootNode = a->rootNode;
00849                 b->left(a->left());
00850                 b->right(a->right());
00851                 b->balance = a->balance;
00852 
00853                 a->rootNode = oldBRoot;
00854                 // Check if we are not overwriting the address
00855                 bool bLeftHack = false, bRightHack = false;
00856                 if (&a->left() != &b) a->left(oldBLeft);
00857                 else // We are
00858                 {   // This means that a->left was b initially, it must be cleaned after the swap
00859                     bLeftHack = true;
00860                 }
00861                 
00862                 if (&a->right() != &b) a->right(oldBRight);
00863                 else // We are
00864                 {   // This means that a->left was b initially, it must be cleaned after the swap
00865                     bRightHack = true;
00866                 }
00867                 a->balance = oldBBalance;
00868 
00869                 // Swap the nodes themselves
00870                 Swap(a, b);
00871 
00872                 // Make sure the child node have correct pointers too
00873                 if (a->left()) a->left()->rootNode = a;
00874                 if (a->right()) a->right()->rootNode = a;
00875                 if (b->left()) b->left()->rootNode = b;
00876                 if (b->right()) b->right()->rootNode = b;
00877 
00878                 // And update the root pointers
00879                 if (a->rootNode) 
00880                 {
00881                     if (aWasLeftOfARoot == 0) a->rootNode->right(a); 
00882                     else if (aWasLeftOfARoot == 1) a->rootNode->left(a);
00883                 }
00884                 if (b->rootNode) 
00885                 {
00886                     if (bWasLeftOfBRoot == 0) b->rootNode->right(b); 
00887                     else if (bWasLeftOfBRoot == 1) b->rootNode->left(b);
00888                 }
00889 
00890                 // Don't let error propagate
00891                 if (bLeftHack) { a->left(0); b->left(0); a->balance = a->right() ? AllNodes::RightTreeIsHeavier : AllNodes::Balanced; }
00892                 if (bRightHack) { a->right(0); b->right(0); a->balance = a->left() ? AllNodes::LeftTreeIsHeavier : AllNodes::Balanced; }
00893             }
00894 
00895 
00898             template <bool bLeft> inline bool replaceWith(NodeT*& target, NodeT** subtree, OperationResult& result, Bool2Type<bLeft> * select)
00899             {
00900                 if (subtree == NULL) return false;
00901 
00902                 result = NeedReBalancing;
00903                 if (*subtree == NULL) return false;
00904 
00905                 if (invSelectSide(*subtree, select) != NULL)
00906                 {
00907                     NodeT *& oldSubtreeNode = (*subtree)->rootNode;
00908                     if (oldSubtreeNode == NULL) return false;
00909                     bool wasOnLeft = oldSubtreeNode->left() == *subtree;
00910                     NodeT *& oldSubtree = wasOnLeft ? oldSubtreeNode->left() : oldSubtreeNode->right();
00911                     if (!replaceWith(target, & invSelectSide(*subtree, select), result, select))
00912                         return false;
00913                     
00914                     // Subtree has probably been deleted, so handle the case
00915                     subtree = wasOnLeft ? &oldSubtreeNode->left() : &oldSubtreeNode->right();
00916                     if (result == NeedReBalancing)  result = balanceShrunk(subtree, (Bool2Type<!bLeft>*)0);
00917                     return true;
00918                 }
00919 
00920                 // Perform the replacement
00921                 // Try the swap method
00922                 NodeT * stSave = target;
00923                 SwapNodes(target, *subtree);
00924                 if (*subtree)
00925                 {   // If the swap was done on a different node than the left node of target
00926                     stSave = *subtree;
00927                     if ((*subtree)->rootNode != NULL) 
00928                     {
00929                         if ((*subtree)->rootNode->left == *subtree)     (*subtree)->rootNode->left(NULL);
00930                         else                                            (*subtree)->rootNode->right(NULL);
00931                     }
00932                 } else result = Ok;
00933                 delete stSave;
00934                 return true;
00935             }
00936 
00938             template <bool bLeft> inline bool replaceAndRebalance(NodeT *& target, NodeT ** subtree, NodeT **& self, NodeT **& relativeRoot, Bool2Type<bLeft> * select)
00939             {
00940                 OperationResult result = Ok;
00941                 if (!replaceWith(target, subtree, result, select))
00942                 {
00943                     if (result == NeedReBalancing)
00944                     {
00945                         result = balanceShrunk(self, select);
00946                         while ((result == NeedReBalancing) && relativeRoot)
00947                         {
00948                             bool left = (*self ==(*relativeRoot)->left());
00949                             self = relativeRoot;
00950                             relativeRoot = getRootOf(*self);
00951                             if (left) result = balanceShrunk(self, (LeftSide*)0);
00952                             else      result = balanceShrunk(self, (RightSide*)0);
00953                         }
00954                     }
00955                     return true;
00956                 } else if (result == NeedReBalancing)
00957                 {   // We can't assume self is correct anymore
00958                     self = &target;
00959                     if (!relativeRoot)
00960                         result = balanceShrunk(self, select);
00961                     else while ((result == NeedReBalancing) && relativeRoot)
00962                     {
00963                         bool left = (*self ==(*relativeRoot)->left());
00964                         self = relativeRoot;
00965                         relativeRoot = getRootOf(*self);
00966                         if (left) result = balanceShrunk(self, (LeftSide*)0);
00967                         else      result = balanceShrunk(self, (RightSide*)0);
00968                     }
00969                 }
00970                 return true;
00971             }
00972 
00973             // Accessors
00974         public:
00976             inline uint32 getSize() const { return (uint32)size; }
00977             
00979             inline bool isEmpty() const { return root == NULL; }
00980             
00982             inline IterT getFirstIterator() { return IterT(root); }
00984             inline const IterT getFirstIterator() const { return IterT(root); }
00985             
00987             inline IterT getLastIterator() { return IterT(NULL); }
00989             inline const IterT getLastIterator() const { return IterT(NULL); }
00990             
00994             inline IterT searchFor(KeyType key) const
00995             {
00996                 if (root == NULL) return getLastIterator();
00997                 NodeT * node = root;
00998                 NodeT * best = NULL;
00999                 CompareT keyToLookFor(key);
01000                 while (node != NULL)
01001                 {
01002                     typename CompareT::Result result = keyToLookFor.Compare(node->key);
01003                     // Found ?
01004                     if (result == Comparator::Equal)    { best = node; break; }
01005                     // No, let's select the correct subtree based on comparison
01006                     else if (result == Comparator::Less)
01007                     {   node = node->left(); }
01008                     else // Less
01009                     {   node = node->right();   }
01010                 }
01011                 return IterT(best != NULL ? best : NULL);               
01012             }
01013 
01017             inline IterT    searchExtreme(const bool lowest) const
01018             {
01019                 if (root == NULL) return getLastIterator();
01020                 NodeT * node = root;
01021                 if (lowest)
01022                 {
01023                     while (node->left() != NULL) node = node->left(); 
01024                 } else
01025                 {
01026                     while (node->right() != NULL) node = node->right(); 
01027                 }
01028                 return IterT(node);
01029             }
01030         };
01031     }
01032 }
01033 
01034 #ifdef _MSC_VER
01035 #pragma warning(pop)
01036 #endif
01037 
01038 #endif  

(C) An X-Ryl669 project 2007

This document describes Unlimited Zooming Interface source code. UZI stands for Unlimited Zooming Interface, and source code license is