Simple Application Framework  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Saf/Algo/Struct/RedBlackTree.h
Go to the documentation of this file.
00001 /*
00002     This file is part of Simple Application Framework (Saf) library.
00003     Copyright (C) 2010 - 2012 Ondrej Danek <ondrej.danek@gmail.com>
00004 
00005     This library is free software: you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published 
00007     by the Free Software Foundation, either version 3 of the License, or
00008     (at your option) any later version.
00009 
00010     Saf is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with Simple Application Framework library. If not, 
00017     see <http://www.gnu.org/licenses/>.
00018 */
00019 
00028 #ifndef SAF_ALGO_STRUCT_REDBLACKTREE_H
00029 #define SAF_ALGO_STRUCT_REDBLACKTREE_H
00030 
00031 #include "../../Type.h"
00032 #include "../../Mem/Alloc.h"
00033 #include "../../Collection/Pair.h"
00034 #include "../Swap.h"
00035 #include "../../Type/IteratorCategory.h"
00036 
00037 namespace Saf
00038 {
00039     namespace Algo
00040     {        
00042         namespace Struct
00043         {
00070             template <class KeyType, class RecType, class KeySelectorType, class CompType> 
00071             class RedBlackTree
00072             {
00073             protected:
00074                 typedef RedBlackTree<KeyType,RecType,KeySelectorType,CompType> MyType;
00075 
00076             protected:
00078                 class Node
00079                 {
00080                 public:
00082                     enum Flags
00083                     {
00084                         BlackFlag = 0,
00085                         RedFlag = 1,
00086                         HeadFlag = 2
00087                     };
00088 
00089                 public:
00091                     Node *m_parent;
00093                     Node *m_child[2];
00095                     RecType m_val;
00097                     Uint8 m_flags;
00098 
00099                 public:
00101                     Node(const RecType& val, Uint8 flags)
00102                         : m_val(val), m_flags(flags)
00103                     {}
00104 
00106                     bool IsHead() const
00107                     {
00108                         return (m_flags & HeadFlag) != 0;
00109                     }
00110 
00112                     bool IsRed() const
00113                     {
00114                         return (m_flags & Node::RedFlag) != 0;
00115                     }
00116 
00118                     Uint8 Colour() const
00119                     {
00120                         return m_flags & 1;
00121                     }
00122 
00124                     void Recolour(Uint8 col)
00125                     {
00126                         m_flags = (m_flags & (~1)) | col;
00127                     }
00128                 };
00129 
00130             public:
00132                 class ConstIterator
00133                 {
00134                 public:
00135                     typedef RecType ValType;
00136                     typedef Type::IteratorCategory::BidirectionalCategory CategoryType;
00137 
00138                 protected:
00140                     Node *m_node;
00141 
00142                     // The tree can access the protected members
00143                     friend class RedBlackTree<KeyType,RecType,KeySelectorType,CompType>;
00144 
00145                 public:
00147                     ConstIterator()
00148                     {}
00149 
00151                     explicit ConstIterator(Node *node)
00152                         : m_node(node)
00153                     {}
00154 
00156                     ConstIterator(const ConstIterator& iter)
00157                         : m_node(iter.m_node)
00158                     {}
00159                     
00161                     ConstIterator& operator=(const ConstIterator& iter)
00162                     {
00163                         m_node = iter.m_node;
00164                         return *this;
00165                     }
00166 
00168                     const RecType& operator*() const
00169                     {
00170                         return m_node->m_val;
00171                     }
00172 
00174                     const RecType* operator->() const
00175                     {
00176                         return &m_node->m_val;
00177                     }
00178 
00180                     ConstIterator& operator++()
00181                     {
00182                         m_node = TreeNext(m_node);
00183                         return *this;
00184                     }
00185 
00187                     ConstIterator operator++(int)
00188                     {
00189                         ConstIterator ci(*this);
00190                         ++(*this);
00191                         return ci;
00192                     }
00193 
00195                     ConstIterator& operator--()
00196                     {
00197                         m_node = TreePrev(m_node);
00198                         return *this;
00199                     }
00200 
00202                     ConstIterator operator--(int)
00203                     {
00204                         ConstIterator ci(*this);
00205                         --(*this);
00206                         return ci;
00207                     }
00208 
00210                     bool operator==(const ConstIterator& ci) const
00211                     {
00212                         return (m_node == ci.m_node);
00213                     }
00214 
00216                     bool operator!=(const ConstIterator& ci) const
00217                     {
00218                         return (m_node != ci.m_node);
00219                     }
00220                 };
00221 
00223                 class Iterator
00224                     : public ConstIterator
00225                 {
00226                 public:
00228                     Iterator()
00229                         : ConstIterator()
00230                     {}
00231 
00233                     explicit Iterator(Node *node)
00234                         : ConstIterator(node)
00235                     {}
00236 
00238                     Iterator(const Iterator& iter)
00239                         : ConstIterator(iter)
00240                     {}
00241                     
00243                     Iterator& operator=(const Iterator& iter)
00244                     {
00245                         ConstIterator::operator=(iter);
00246                         return *this;
00247                     }
00248 
00250                     RecType& operator*() const
00251                     {
00252                         return this->m_node->m_val;
00253                     }
00254 
00256                     RecType* operator->() const
00257                     {
00258                         return &this->m_node->m_val;
00259                     }
00260 
00262                     Iterator& operator++()
00263                     {
00264                         ++(*((ConstIterator *)this));
00265                         return *this;
00266                     }
00267 
00269                     Iterator operator++(int)
00270                     {
00271                         Iterator it(*this);
00272                         ++(*this);
00273                         return it;
00274                     }
00275 
00277                     Iterator& operator--()
00278                     {
00279                         --(*((ConstIterator *)this));
00280                         return *this;
00281                     }
00282 
00284                     Iterator operator--(int)
00285                     {
00286                         Iterator it(*this);
00287                         --(*this);
00288                         return it;
00289                     }
00290                 };
00291 
00292             private:
00298                 Node *m_head;
00300                 Size m_elems;
00302                 CompType m_comp;
00304                 KeySelectorType m_keyExtract;
00305 
00306             protected:
00308                 Node *AllocNode(const RecType& val, Node *parent, Uint8 flags)
00309                 {
00310                     Node *n = SAF_NEW Node(val, flags);
00311                     n->m_parent = parent;
00312                     n->m_child[0] = Head();
00313                     n->m_child[1] = Head();
00314                     return n;
00315                 }
00316 
00318                 Node* Head() const
00319                 {
00320                     return m_head;
00321                 }
00322 
00324                 Node*& Root() const
00325                 {
00326                     return Head()->m_parent;
00327                 }
00328 
00330                 Node*& Leftmost() const
00331                 {
00332                     return Head()->m_child[0];
00333                 }
00334 
00336                 Node*& Rightmost() const
00337                 {
00338                     return Head()->m_child[1];
00339                 }
00340 
00342                 bool IsLeftChild(Node *n) const
00343                 {
00344                     return n == n->m_parent->m_child[0];
00345                 }
00346 
00348                 void Rotate(Node* root, Int32 dir)
00349                 {
00350                     Node *grandpa = root->m_parent;
00351                     Node *nodeA = root->m_child[1-dir];
00352                     Node *nodeB = nodeA->m_child[dir];
00353 
00354                     nodeA->m_parent = grandpa;
00355                     if (grandpa->IsHead())
00356                     {
00357                         Root() = nodeA;
00358                     }
00359                     else
00360                     {
00361                         grandpa->m_child[(root == grandpa->m_child[0]) ? 0 : 1] = nodeA;
00362                     }
00363                     
00364                     nodeA->m_child[dir] = root;
00365                     root->m_parent = nodeA;
00366 
00367                     root->m_child[1-dir] = nodeB;
00368                     if (!nodeB->IsHead())
00369                     {
00370                         nodeB->m_parent = root;
00371                     }
00372                 }
00373 
00376                 Node* TreeLowerBound(const KeyType& key) const
00377                 {
00378                     Node *node = Root();
00379                     Node *lowerBound = Head();
00380 
00381                     while (!node->IsHead())
00382                     {
00383                         if (m_comp(m_keyExtract(node->m_val), key))
00384                         {
00385                             node = node->m_child[1];
00386                         }
00387                         else
00388                         {
00389                             lowerBound = node;
00390                             node = node->m_child[0];
00391                         }
00392                     }
00393 
00394                     return lowerBound;
00395                 }
00396 
00399                 Node* TreeUpperBound(const KeyType& key) const
00400                 {
00401                     Node *node = Root();
00402                     Node *upperBound = Head();
00403 
00404                     while (!node->IsHead())
00405                     {
00406                         if (m_comp(key, m_keyExtract(node->m_val)))
00407                         {
00408                             upperBound = node;
00409                             node = node->m_child[0];
00410                         }
00411                         else
00412                         {
00413                             node = node->m_child[1];
00414                         }
00415                     }
00416 
00417                     return upperBound;
00418                 }
00419 
00421                 static Node* TreePrev(Node *node)
00422                 {
00423                     if (node->IsHead())
00424                     {
00425                         return node->m_child[1];
00426                     }
00427 
00428                     if (!node->m_child[0]->IsHead())
00429                     {
00430                         return TreeMax(node->m_child[0]);
00431                     }
00432 
00433                     Node *parent = node->m_parent;
00434                     while (!parent->IsHead() && node == parent->m_child[0])
00435                     {
00436                         node = parent;
00437                         parent = parent->m_parent;
00438                     }
00439 
00440                     return parent;
00441                 }
00442 
00444                 static Node* TreeNext(Node *node)
00445                 {
00446                     if (node->IsHead())
00447                     {
00448                         return node;
00449                     }
00450 
00451                     if (!node->m_child[1]->IsHead())
00452                     {
00453                         return TreeMin(node->m_child[1]);
00454                     }
00455 
00456                     Node *parent = node->m_parent;
00457                     while (!parent->IsHead() && node == parent->m_child[1])
00458                     {
00459                         node = parent;
00460                         parent = parent->m_parent;
00461                     }
00462 
00463                     return parent;
00464                 }
00465 
00467                 static Node* TreeMin(Node *root)
00468                 {
00469                     while (!root->m_child[0]->IsHead())
00470                     {
00471                         root = root->m_child[0];
00472                     }
00473 
00474                     return root;
00475                 }
00476 
00478                 static Node* TreeMax(Node *root)
00479                 {
00480                     while (!root->m_child[1]->IsHead())
00481                     {
00482                         root = root->m_child[1];
00483                     }
00484 
00485                     return root;
00486                 }
00487 
00488             private:
00490                 void Init()
00491                 {
00492                     // Allocate a head node, but do not construct the RecType object                    
00493                     Mem::OperatorNew(m_head, SAF_SOURCE_LOCATION);
00494                     m_head->m_flags = Node::HeadFlag | Node::BlackFlag;
00495                     
00496                     // Init tree
00497                     Root() = Head();
00498                     Leftmost() = Head();
00499                     Rightmost() = Head();
00500                 }
00501 
00502             public:
00507                 RedBlackTree() 
00508                     : m_head(nullptr), m_elems(0)
00509                 {
00510                     Init();
00511                 }
00512 
00514                 RedBlackTree(const MyType &rbt) 
00515                     : m_head(nullptr), m_elems(0)
00516                 { 
00517                     Init();
00518                     *this = rbt; 
00519                 }
00520 
00522                 ~RedBlackTree() 
00523                 { 
00524                     Free();
00525                     Mem::OperatorDelete(m_head);
00526                 }
00527 
00533                 MyType& Free() 
00534                 {                    
00535                     if (!IsEmpty())
00536                     {
00537                         Node *node = Root(), *nextNode;
00538 
00539                         while (node != Head())
00540                         {
00541                             if (!node->m_child[0]->IsHead())
00542                             {
00543                                 nextNode = node->m_child[0];
00544                                 node->m_child[0] = Head();
00545                                 node = nextNode;
00546                             }
00547                             else if (!node->m_child[1]->IsHead())
00548                             {
00549                                 nextNode = node->m_child[1];
00550                                 node->m_child[1] = Head();
00551                                 node = nextNode;
00552                             }
00553                             else
00554                             {
00555                                 nextNode = node->m_parent;
00556                                 Mem::Delete(node);
00557                                 node = nextNode;
00558                             }
00559                         }
00560 
00561                         Root() = Head();
00562                         Leftmost() = Head();
00563                         Rightmost() = Head();
00564                         m_elems = 0;
00565                     }
00566                 
00567                     return *this;
00568                 }
00569 
00579                 MyType& operator=(const MyType& rbt)
00580                 {
00581                     if (&rbt != this)
00582                     {
00583                         Free();
00584 
00585                         if (!rbt.IsEmpty())
00586                         {
00587                             try
00588                             {
00589                                 Root() = AllocNode(rbt.Root()->m_val, Head(), Node::BlackFlag);
00590                                 m_elems = 1;
00591 
00592                                 Node *nDst = Root(), *nSrc = rbt.Root();
00593 
00594                                 while (nDst != Head())
00595                                 {
00596                                     if (nDst->m_child[0]->IsHead() && !nSrc->m_child[0]->IsHead())
00597                                     {
00598                                         nSrc = nSrc->m_child[0];
00599                                         nDst->m_child[0] = AllocNode(nSrc->m_val, nDst, nSrc->m_flags);
00600                                         nDst = nDst->m_child[0];
00601                                         m_elems++;                                
00602                                     }
00603                                     else if (nDst->m_child[1]->IsHead() && !nSrc->m_child[1]->IsHead())
00604                                     {
00605                                         nSrc = nSrc->m_child[1];
00606                                         nDst->m_child[1] = AllocNode(nSrc->m_val, nDst, nSrc->m_flags);
00607                                         nDst = nDst->m_child[1];
00608                                         m_elems++;                                
00609                                     }
00610                                     else
00611                                     {
00612                                         nDst = nDst->m_parent;
00613                                         nSrc = nSrc->m_parent;
00614                                     }
00615                                 }
00616 
00617                                 Leftmost() = TreeMin(Root());
00618                                 Rightmost() = TreeMax(Root());
00619                             }
00620                             catch (...)
00621                             {
00622                                 Free();
00623                                 throw;
00624                             }
00625                         }
00626                     }
00627 
00628                     return *this;
00629                 }
00630 
00636                 MyType& Swap(MyType& rbt)
00637                 {
00638                     if (this != &rbt)
00639                     {
00640                         Algo::Swap(m_head, rbt.m_head);
00641                         Algo::Swap(m_elems, rbt.m_elems);
00642                         Algo::Swap(m_comp, rbt.m_comp);
00643                         Algo::Swap(m_keyExtract, rbt.m_keyExtract);
00644                     }
00645 
00646                     return *this;
00647                 }
00648 
00654                 bool IsEmpty() const 
00655                 { 
00656                     return (m_elems == 0);
00657                 }
00658 
00664                 Size Elements() const
00665                 {
00666                     return m_elems;
00667                 }
00668 
00681                 Collection::Pair<Iterator,bool> Insert(const RecType& val)
00682                 {
00683                     // Handle inserts into an empty tree
00684                     if (IsEmpty())
00685                     {                        
00686                         Node *newRoot = AllocNode(val, Head(), Node::BlackFlag);
00687                         
00688                         Root() = newRoot;
00689                         Leftmost() = newRoot;
00690                         Rightmost() = newRoot;
00691                         m_elems = 1;
00692 
00693                         return Collection::Pair<Iterator,bool>(Iterator(newRoot), true);
00694                     }
00695 
00696                     // Non-empty tree -> find where to put the new node
00697                     Node *node = Root(), *parent = Head(), *lowerBound = Head();
00698                     Int32 dir = 0;
00699 
00700                     while (!node->IsHead())
00701                     {
00702                         if (m_comp(m_keyExtract(val), m_keyExtract(node->m_val)))
00703                         {
00704                             dir = 0;
00705                         }
00706                         else
00707                         {
00708                             dir = 1;
00709                             lowerBound = node;
00710                         }
00711 
00712                         parent = node;
00713                         node = node->m_child[dir];
00714                     }                    
00715 
00716                     // Check if unique by checking the value of the lower bound
00717                     if (!lowerBound->IsHead())
00718                     {
00719                         if (!m_comp(m_keyExtract(lowerBound->m_val), m_keyExtract(val)))
00720                         {
00721                             // Key with equivalent ordering already exists in the tree
00722                             return Collection::Pair<Iterator,bool>(Iterator(lowerBound), false);
00723                         }
00724                     }
00725 
00726                     // Insert a new element
00727                     Node *newNode = AllocNode(val, parent, Node::RedFlag);
00728                     m_elems++;
00729 
00730                     node = newNode;
00731                     parent->m_child[dir] = node;
00732 
00733                     if (parent == Leftmost() && dir == 0)
00734                     {
00735                         Leftmost() = node; // Update the left-most element
00736                     }
00737                     else if (parent == Rightmost() && dir != 0)
00738                     {
00739                         Rightmost() = node; // Update the right-most element
00740                     }
00741 
00742                     // Rebalance
00743                     while (parent->IsRed())
00744                     {
00745                         dir = IsLeftChild(parent) ? 0 : 1;
00746                         
00747                         Node *grandpa = parent->m_parent;
00748                         Node *uncle = grandpa->m_child[1-dir];
00749 
00750                         if (uncle->IsRed())
00751                         {
00752                             // Uncle is red -> move red to grandpa
00753                             parent->Recolour(Node::BlackFlag);
00754                             uncle->Recolour(Node::BlackFlag);
00755                             grandpa->Recolour(Node::RedFlag);
00756                             node = grandpa;
00757                         }
00758                         else
00759                         {
00760                             // Uncle is black -> rotate subtrees
00761                             if (node == parent->m_child[1-dir])
00762                             {
00763                                 Rotate(parent, dir);
00764                                 node = parent;
00765                                 parent = node->m_parent;
00766                             }
00767 
00768                             parent->Recolour(Node::BlackFlag);
00769                             grandpa->Recolour(Node::RedFlag);
00770                             Rotate(grandpa, 1-dir);
00771                         }
00772 
00773                         parent = node->m_parent;
00774                     }
00775 
00776                     Root()->Recolour(Node::BlackFlag); // Root is always black
00777                     return Collection::Pair<Iterator,bool>(Iterator(newNode), true);
00778                 }
00779 
00789                 Iterator Erase(Iterator iter)
00790                 {
00791                     // Iterator to be returned
00792                     Iterator succIter(iter.m_node);
00793                     ++succIter;
00794 
00795                     // Erase
00796                     Node *node = iter.m_node;
00797                     Node *left = node->m_child[0], *right = node->m_child[1];
00798                     Node *parent = node->m_parent;
00799                     bool needRebalance;
00800 
00801                     // Decide which element will replace the erased node and relink
00802                     if (left->IsHead() || right->IsHead())
00803                     {                        
00804                         // Lift left or right child
00805                         Node *next = left->IsHead() ? right : left;
00806                         needRebalance = !node->IsRed();
00807 
00808                         // Relink the subtree
00809                         if (!next->IsHead())
00810                         {
00811                             next->m_parent = parent;
00812                         }
00813 
00814                         if (parent->IsHead())
00815                         {
00816                             Root() = next;
00817                         }
00818                         else
00819                         {
00820                             parent->m_child[(node == parent->m_child[0]) ? 0 : 1] = next;
00821                         }
00822 
00823                         // Fix left-most and right-most elements
00824                         if (node == Leftmost())
00825                         {
00826                             Leftmost() = succIter.m_node;
00827                         }
00828 
00829                         if (node == Rightmost())
00830                         {
00831                             Rightmost() = left->IsHead() ? parent : TreeMax(left);
00832                         }
00833 
00834                         // Proceed with rebalancing next                        
00835                         node = next;
00836                     }
00837                     else
00838                     {
00839                         // Lift successor
00840                         Node *next = succIter.m_node, *nextParent = next->m_parent;                        
00841 
00842                         // Recolour
00843                         needRebalance = !next->IsRed();
00844                         next->Recolour(node->Colour());
00845 
00846                         // The new root of the subtree is next
00847                         next->m_parent = parent;
00848                         next->m_child[0] = left;
00849                         left->m_parent = next;
00850 
00851                         if (parent->IsHead())
00852                         {
00853                             Root() = next;
00854                         }
00855                         else
00856                         {
00857                             parent->m_child[(node == parent->m_child[0]) ? 0 : 1] = next;
00858                         }
00859 
00860                         // Right child of the succesor will be the first rebalanced node
00861                         node = next->m_child[1];                        
00862 
00863                         // Fix the right half of the subtree
00864                         if (next == right)
00865                         {
00866                             // Successor is next to the erased node
00867                             parent = next;
00868                         }
00869                         else
00870                         {
00871                             parent = nextParent;
00872                             if (!node->IsHead())
00873                             {
00874                                 node->m_parent = parent;
00875                             }
00876                             parent->m_child[0] = node;
00877                             next->m_child[1] = right;
00878                             right->m_parent = next;
00879                         }
00880                     }
00881 
00882                     // Rebalance
00883                     if (needRebalance)
00884                     {
00885                         while (!node->IsRed() && node != Root())
00886                         {
00887                             Int32 dir = (node == parent->m_child[0]) ? 0 : 1; // Fix left or right subtree
00888                             Node *sibling = parent->m_child[1-dir];
00889 
00890                             if (sibling->IsRed())
00891                             {
00892                                 // Rotate red from left or right subtree
00893                                 sibling->Recolour(Node::BlackFlag);
00894                                 parent->Recolour(Node::RedFlag);
00895                                 Rotate(parent, dir);
00896                                 sibling = parent->m_child[1-dir];
00897                             }
00898 
00899                             if (!sibling->m_child[0]->IsRed() && !sibling->m_child[1]->IsRed())
00900                             {
00901                                 // Redden left/right subtree with black children
00902                                 sibling->Recolour(Node::RedFlag);
00903                                 node = parent;
00904                                 parent = node->m_parent;
00905                             }
00906                             else
00907                             {
00908                                 // Rearrange left/right subtree
00909                                 if (!sibling->m_child[1-dir]->IsRed())
00910                                 {
00911                                     sibling->m_child[dir]->Recolour(Node::BlackFlag);
00912                                     sibling->Recolour(Node::RedFlag);
00913                                     Rotate(sibling, 1-dir);
00914                                     sibling = parent->m_child[1-dir];
00915                                 }
00916 
00917                                 sibling->Recolour(parent->Colour());
00918                                 parent->Recolour(Node::BlackFlag);
00919                                 sibling->m_child[1-dir]->Recolour(Node::BlackFlag);
00920                                 Rotate(parent, dir);
00921                                 break;
00922                             }
00923                         }
00924 
00925                         // Stopping node is black
00926                         node->Recolour(Node::BlackFlag);
00927                     }
00928 
00929                     // Free node
00930                     --m_elems;
00931                     Mem::Delete(iter.m_node);                    
00932                     
00933                     return succIter;
00934                 }
00935 
00942                 Iterator LowerBound(const KeyType& key)
00943                 {
00944                     return Iterator(TreeLowerBound(key));
00945                 }
00946 
00953                 ConstIterator LowerBound(const KeyType& key) const
00954                 {
00955                     return ConstIterator(TreeLowerBound(key));
00956                 }
00957 
00964                 Iterator UpperBound(const KeyType& key)
00965                 {
00966                     return Iterator(TreeUpperBound(key));
00967                 }
00968 
00975                 ConstIterator UpperBound(const KeyType& key) const
00976                 {
00977                     return ConstIterator(TreeUpperBound(key));
00978                 }
00979 
00987                 Iterator Find(const KeyType& key)
00988                 {
00989                     Iterator it = LowerBound(key);
00990 
00991                     if (it == End() || m_comp(key, m_keyExtract(*it)))
00992                     {
00993                         return End();
00994                     }
00995 
00996                     return it;
00997                 }
00998 
01006                 ConstIterator Find(const KeyType& key) const
01007                 {
01008                     ConstIterator it = LowerBound(key);
01009 
01010                     if (it == End() || m_comp(key, m_keyExtract(*it)))
01011                     {
01012                         return End();
01013                     }
01014 
01015                     return it;
01016                 }
01017 
01023                 bool Contains(const KeyType& key) const
01024                 {
01025                     return (Find(key) != End());
01026                 }
01027 
01029                 Iterator Begin()
01030                 {
01031                     return Iterator(Leftmost());
01032                 }
01033 
01035                 ConstIterator Begin() const
01036                 {
01037                     return ConstIterator(Leftmost());
01038                 }
01039 
01041                 Iterator End()
01042                 {
01043                     return Iterator(Head());
01044                 }
01045 
01047                 ConstIterator End() const
01048                 {
01049                     return ConstIterator(Head());
01050                 }
01051 
01053                 Iterator Front()
01054                 {
01055                     return Begin();
01056                 }
01057 
01059                 ConstIterator Front() const
01060                 {
01061                     return Begin();
01062                 }
01063 
01065                 Iterator Back()
01066                 {
01067                     return Iterator(Rightmost());
01068                 }
01069 
01071                 ConstIterator Back() const
01072                 {
01073                     return ConstIterator(Rightmost());
01074                 }
01075             };
01076         }
01077 
01079         // Swap specialization for red/black trees.
01080         template <class KeyType, class RecType, class KeySelectorType, class CompType> 
01081         struct SwapFunc< Struct::RedBlackTree<KeyType,RecType,KeySelectorType,CompType> >
01082         {
01083             void operator()(Struct::RedBlackTree<KeyType,RecType,KeySelectorType,CompType>& x, 
01084                 Struct::RedBlackTree<KeyType,RecType,KeySelectorType,CompType>& y)
01085             {
01086                 x.Swap(y);
01087             }
01088         };
01090     }
01091 }
01092 
01093 #endif