Multiset.H

00001 
00002 /*
00003   This file is part of Aleph system
00004 
00005   Copyright (c) 2002, 2003, 2004, 2005, 2006
00006   UNIVERSITY LOS ANDES (ULA) Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA  
00007 
00008   - Center of Studies in Microelectronics & Distributed Systems (CEMISID) 
00009   - ULA Computer Science Department
00010   - FUNDACITE Mérida - Ministerio de Ciencia y Tecnología
00011 
00012   PERMISSION TO USE, COPY, MODIFY AND DISTRIBUTE THIS SOFTWARE AND ITS
00013   DOCUMENTATION IS HEREBY GRANTED, PROVIDED THAT BOTH THE COPYRIGHT
00014   NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES OF THE
00015   SOFTWARE, DERIVATIVE WORKS OR MODIFIED VERSIONS, AND ANY PORTIONS
00016   THEREOF, AND THAT BOTH NOTICES APPEAR IN SUPPORTING DOCUMENTATION.
00017 
00018   Aleph is distributed in the hope that it will be useful, but WITHOUT
00019   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00020   or FITNESS FOR A PARTICULAR PURPOSE.
00021 
00022   UNIVERSIDAD DE LOS ANDES requests users of this software to return to 
00023 
00024   Leandro Leon
00025   CEMISID 
00026   Ed La Hechicera 
00027   3er piso, ala sur
00028   Facultad de Ingenieria 
00029   Universidad de Los Andes 
00030   Merida - REPÚBLICA BOLIVARIANA DE VENEZUELA    or
00031 
00032   lrleon@ula.ve
00033 
00034   any improvements or extensions that they make and grant Universidad 
00035   de Los Andes (ULA) the rights to redistribute these changes. 
00036 
00037   Aleph is (or was) granted by: 
00038   - Consejo de Desarrollo Cientifico, Humanistico, Tecnico de la ULA 
00039     (CDCHT)
00040   - Fundacite Mérida
00041 */
00042 
00043 /*
00044        Aleph implementation of multiset C++ standard container
00045 */
00046 
00047 # ifndef AH_MULTISET_H
00048 # define AH_MULTISET_H
00049 
00050 # include <memory>
00051 # include <ah_stdc++_utils.H>
00052 # include <tpl_dnode.H>
00053 # include <tpl_treapRk.H>
00054 
00055 namespace Aleph
00056 {
00057 
00079     template <class T, 
00080            class Compare = Aleph::less<T>,
00081            template <class, class> class Tree = Treap_Rk_Vtl
00082            >
00083 class multiset
00084 {
00085 public:
00086 
00088   typedef T value_type;
00089 
00091   typedef typename multiset::value_type & reference;
00092 
00094   typedef const typename multiset::value_type & const_reference;
00095 
00097   typedef size_t size_type;
00098 
00100   typedef T key_type;
00101 
00102 private:
00103 
00104   typedef Tree<T, Compare> Tree_Type;
00105 
00106   mutable Tree_Type tree;
00107 
00108   mutable size_t num_elem;
00109 
00110       // Definición de nodo que manejerá el árbol
00111   struct Node : public Tree<T, Compare>::Node
00112   {
00113     mutable Dlink key_list;   // lista de claves repetidas
00114     mutable size_t num_elem;  // número de elementos repetidos.
00115 
00116     Node () : num_elem (0) { /* empty */ }
00117 
00118     Node (const T & k) : Tree_Type::Node (k), num_elem (0) { /* empty */ }
00119 
00120     void copy_list (Dlink & l)
00121     {
00122       for (typename Dnode<T>::Iterator it (&l); it.has_current (); it.next ())
00123      {
00124        Dnode<T> * node = new Dnode<T> (it.get_current ()->get_data ());
00125        key_list.append(node);
00126        ++num_elem;
00127      }
00128     }
00129 
00130     Node * operator = (const Node & node)
00131     {
00132       if (this == &node)
00133      return *this;
00134 
00135       *static_cast<typename Tree_Type::Node*> (this) = node;
00136       num_elem = 0;
00137 
00138       key_list.remove_all_and_delete();
00139       copy_list(&node.key_list);
00140     }
00141 
00142     Node (const Node & p) : Tree_Type::Node (p), num_elem (0)
00143     {
00144       copy_list(p.key_list);
00145     }
00146 
00147     ~Node ()
00148     {
00149       key_list.remove_all_and_delete();
00150     }
00151   };
00152 
00153 public:  
00154 
00159   class iterator
00160   {
00161   private:
00162 
00163     friend class multiset<T, Compare, Tree>;
00164     
00165     typedef typename Tree_Type::Iterator Iterator;
00166     
00167     mutable multiset * multiset_ptr;
00168 
00169     Iterator tree_itor;
00170 
00171     typename Dnode<T>::Iterator list_itor;
00172 
00173     bool overflow;
00174 
00175     bool underflow;
00176 
00177         /* Coloca list_itor en un nodo de la lista en tree_itor */
00178     void set_list_itor_in_node (Dnode<T> * list_node)
00179     {
00180       Node * node = static_cast<Node*> (tree_itor.get_current ());
00181 
00182       list_itor = typename Dnode<T>::Iterator (&node->key_list, list_node);
00183     }
00184 
00185     iterator (multiset * mset_ptr, 
00186            Node *     curr_tree_node,
00187            Dlink &    key_list,
00188            Dnode<T> * curr_list_node) 
00189       : multiset_ptr (mset_ptr),
00190      tree_itor (mset_ptr->tree, curr_tree_node), 
00191      list_itor (&key_list, curr_list_node),
00192      overflow (false), underflow (false)
00193     {
00194       I (curr_list_node->get_data () == curr_tree_node->get_key ());
00195       I (multiset_ptr->tree.search (KEY (curr_tree_node)) != NULL);
00196       I (&curr_tree_node->key_list == &key_list);
00197     }
00198 
00199     iterator (multiset * mset_ptr, Node * curr_tree_node)
00200       : multiset_ptr (mset_ptr),
00201      tree_itor (mset_ptr->tree, curr_tree_node), 
00202      list_itor (&curr_tree_node->key_list), 
00203      overflow (false), underflow (false)
00204     {
00205       I (mset_ptr->tree.search (KEY (curr_tree_node)) != NULL);
00206     }
00207 
00208     void default_init ()
00209     {
00210       if (tree_itor.has_current ())
00211      {
00212        list_itor.reset
00213          (&static_cast<Node*> (tree_itor.get_current ())->key_list);
00214 
00215        underflow = overflow = false;
00216      }
00217       else
00218      underflow = overflow = true;
00219     }
00220 
00221     iterator (const multiset & ms)
00222       :  multiset_ptr (const_cast<multiset*> (&ms)), tree_itor (ms.tree)
00223     {
00224       default_init ();
00225     }
00226 
00227     bool has_current () const 
00228     {
00229       return tree_itor.has_current () and list_itor.has_current (); 
00230     }
00231 
00232     T & get_current () { return list_itor.get_current ()->get_data (); }
00233 
00234   public:
00235 
00237     typedef typename multiset<T>::value_type      value_type;
00238 
00241     typedef typename multiset<T>::size_type       difference_type;
00242 
00244     typedef typename multiset<T>::value_type *    pointer;
00245 
00247     typedef typename multiset<T>::reference       reference;
00248 
00250     typedef const typename multiset<T>::reference const_reference;
00251 
00252     iterator (multiset * mset_ptr)
00253       : multiset_ptr (mset_ptr), tree_itor (multiset_ptr->tree) 
00254     {
00255       default_init ();
00256     }
00257 
00259     iterator () 
00260     {
00261       underflow = overflow = true;
00262     }
00263 
00265     T & operator * ()
00266     {
00267       return get_current ();
00268     }
00269 
00271     T * operator -> ()
00272     {
00273       return & get_current ();
00274     }
00275 
00276   private:
00277 
00278     void goto_begin ()
00279     {
00280       tree_itor.reset_first ();
00281       
00282       if (tree_itor.has_current ())
00283      {
00284        list_itor.reset
00285          (& static_cast<Node*> (tree_itor.get_current ())->key_list);
00286 
00287        underflow = false;
00288      }
00289       else
00290      underflow = true;
00291     }
00292 
00293     void goto_last ()
00294     {
00295       tree_itor.reset_last ();
00296       
00297       if (tree_itor.has_current ())
00298      {
00299        list_itor.reset
00300          (& static_cast<Node*> (tree_itor.get_current ())->key_list);
00301        list_itor.reset_last ();
00302        overflow = false;
00303      }
00304       else
00305      overflow = true;
00306     }
00307 
00308     void goto_end ()
00309     {
00310       tree_itor.reset_last ();
00311       
00312       if (tree_itor.has_current ())
00313      {
00314        list_itor.reset 
00315          (& static_cast<Node*> (tree_itor.get_current ())->key_list);
00316 
00317        list_itor.prev ();
00318        tree_itor.next ();
00319        underflow = false;
00320      }
00321       else
00322      underflow = true;
00323 
00324       overflow = true;
00325     }
00326 
00327     void forward ()
00328     {
00329       if (underflow)
00330      {
00331        goto_begin ();
00332        return;
00333      }
00334 
00335       list_itor.next (); // Avanza elementos repetidos
00336 
00337       if (not list_itor.has_current ()) 
00338      { 
00339        tree_itor.next (); 
00340 
00341        if (tree_itor.has_current ())
00342          {
00343            Dlink * list = 
00344           &static_cast<Node*> (tree_itor.get_current ())->key_list;
00345            list_itor.reset (list);
00346          }
00347        else
00348          overflow = true;
00349      }
00350     }
00351 
00352     void backward ()
00353     {
00354       if (overflow)
00355      {
00356        goto_last ();
00357        return;
00358      }
00359 
00360       list_itor.prev ();
00361 
00362       if (not list_itor.has_current ())
00363      {
00364        tree_itor.prev ();
00365 
00366        if (tree_itor.has_current ())
00367          {
00368            Dlink * list = 
00369           &static_cast<Node*> (tree_itor.get_current ())->key_list;
00370            list_itor.reset (list);
00371            list_itor.reset_last ();
00372          }
00373        else
00374          underflow = true;
00375      }
00376     }
00377 
00378     void del ()
00379     {
00380       Dnode<T> * list_node = list_itor.del ();
00381       Node * tree_node = static_cast<Node*> (tree_itor.get_current ());
00382             
00383       delete list_node;
00384 
00385       --tree_node->num_elem;
00386 
00387       --multiset_ptr->num_elem;
00388 
00389       if (tree_node->num_elem == 0)
00390      {
00391        tree_itor.del ();
00392        delete tree_node;
00393 
00394        if (tree_itor.has_current ())
00395          {
00396            Dlink * list = 
00397           &static_cast<Node*> (tree_itor.get_current ())->key_list;
00398            list_itor.reset (list);
00399          }
00400        else
00401          overflow = true;
00402      }
00403     }
00404 
00405   public:
00406 
00409     T & operator ++ ()
00410     {
00411       forward ();
00412 
00413       return get_current ();
00414     }
00415 
00417     T & operator ++ (int)
00418     {
00419       T & return_value = get_current ();
00420 
00421       forward ();
00422 
00423       return return_value;
00424     }
00425 
00428     T & operator -- ()
00429     {
00430       backward ();
00431 
00432       return get_current ();
00433     }
00434 
00436     T & operator -- (int)
00437     {
00438       T & return_value = get_current ();
00439 
00440       backward ();
00441 
00442       return return_value;
00443     }
00444     
00445     /* TODO: Estas funciones pueden optimizarse para que avancen por
00446        contadores de nodos */  
00447 
00450     T & operator += (size_type n)
00451     {
00452       for (int i = 0; i < n; ++i)
00453         forward ();
00454 
00455       return get_current ();
00456     } 
00457 
00460     T & operator -= (size_type n)
00461     {
00462       for (int i = 0; i < n; ++i)
00463         backward ();
00464       
00465       return get_current ();
00466     } 
00467 
00469     bool operator == (const iterator & itor) const
00470     {
00471       if (overflow == itor.overflow and underflow == itor.underflow)
00472      return true;
00473 
00474       return tree_itor == itor.tree_itor and list_itor == itor.list_itor; 
00475     }
00476 
00478     bool operator != (const iterator & itor) const
00479     {
00480       return not (*this == itor);
00481     }
00482 
00483     bool verify (const multiset & _multiset) const
00484     {
00485       return tree_itor.verify ( (Tree_Type*)& (_multiset.tree));
00486     }
00487 
00488     bool verify (const iterator & it) const
00489     {
00490       return tree_itor.verify (it.tree_itor);
00491     }
00492   }; // class iterator;
00493 
00495   typedef typename multiset::iterator const_iterator;
00496 
00498   typedef typename multiset::iterator reverse_iterator;
00499   
00501   typedef typename multiset::iterator const_reverse_iterator;
00502 
00504   multiset () : num_elem (0) { /* empty */  }
00505 
00506 private:
00507 
00508   void copy (const multiset & c)
00509   {
00510     Node * tree_node = copyRec<Node> (static_cast<Node*> (c.tree.getRoot ()));
00511 
00512     tree.getRoot () = tree_node;
00513   }
00514 
00515 public:
00516  
00518   multiset (const multiset & c) : num_elem (c.num_elem)
00519   {
00520     copy (c);
00521   }
00522 
00538       template <typename Itor> 
00539   multiset (Itor beg, Itor end) : num_elem (0)
00540   {
00541     while (beg != end)
00542       insert (beg++);
00543   }
00544 
00547   ~multiset () 
00548   { 
00549     destroyRec (tree.getRoot());
00550   }  
00551 
00553   multiset & operator = (const multiset & c)
00554   {
00555     if (this == &c)
00556       return *this;
00557 
00558     destroyRec (tree.getRoot());
00559 
00560     copy (c);
00561 
00562     num_elem = c.num_elem;
00563 
00564     return *this;
00565   }
00566 
00568   size_type size () const { return num_elem; }
00569 
00571   bool empty () const
00572   {
00573     return COUNT (tree.getRoot ()) == 0;
00574   }
00575 
00578   bool operator == (const multiset & c) const
00579   {
00580     if (this == &c)
00581       return true;
00582 
00583     if (size () != c.size ())
00584       return false;
00585 
00586     iterator itor1 (*this), itor2 (c);
00587 
00588     while (itor1.has_current () and itor2.has_current ())
00589       {
00590      if (itor1.get_current () != itor2.get_current ())
00591        return false;
00592 
00593      itor1.forward ();
00594      itor2.forward ();
00595       }
00596     
00597     return true;
00598   }
00599 
00602   bool operator != (const multiset & c) const
00603   {
00604     return not (*this == c);
00605   }
00606 
00609   bool operator < (const multiset & c) const
00610   {
00611     if (this == &c)
00612       return false;
00613 
00614     iterator itor1 (*this), itor2 (c);
00615 
00616     while (itor1.has_current () and itor2.has_current ())
00617       {
00618      if (itor1.get_current () < itor2.get_current ())
00619        return true;
00620      else if (itor2.get_current () < itor1.get_current ())
00621        return false; // no son iguales
00622        
00623      itor1.forward ();
00624      itor2.forward ();
00625       }
00626     
00627     if (itor1.has_current ()) /* |*this| >= |c| */
00628       return false;
00629 
00630     return itor2.has_current ();
00631   }
00632 
00635   bool operator > (const multiset & c) const
00636   {
00637     return not (*this == c or *this < c);
00638   }
00639 
00642   bool operator <= (const multiset & c) const
00643   {
00644     return not (*this > c );
00645   }
00646 
00649   bool operator >= (const multiset & c) const
00650   {
00651     return not (*this < c);
00652   }
00653 
00661   size_type count (const T & value) const
00662   {
00663     Node * p = static_cast<Node*> (tree.search (value));
00664 
00665     if (p == NULL)
00666       return 0;
00667 
00668     return p->num_elem;
00669   } 
00670 
00688   iterator find (const T & value) const
00689   { 
00690     Node * node = static_cast<Node*> (tree.search (value));
00691 
00692     if (node == NULL)
00693       return end ();
00694 
00695     iterator itor (*this);
00696 
00697     itor.tree_itor.reset_to_node (node);
00698     itor.list_itor.reset (&node->key_list);
00699 
00700     return itor;
00701   }
00702 
00718   iterator lower_bound (const T & value) const
00719   {
00720     if (size () == 0)
00721       throw std::underflow_error ("multiset is empty");
00722 
00723     Node * tree_node = static_cast<Node*> (tree.search (value));
00724 
00725     if (tree_node == NULL)
00726       return end ();
00727 
00728     return iterator (this, tree_node);
00729   }
00730 
00746   iterator upper_bound (const T & value) const
00747   {
00748     if (size () == 0)
00749       throw std::underflow_error ("multiset is empty");
00750 
00751     Node * tree_node = static_cast<Node*> (tree.search (value));
00752 
00753     if (tree_node == NULL)
00754       return end ();
00755 
00756     iterator it (this, tree_node);
00757     it.list_itor.reset_last ();
00758 
00759     return it;
00760   }
00761 
00764   void swap (multiset & c)
00765   {
00766     Aleph::swap (tree.getRoot (), c.tree.getRoot ());
00767     Aleph::swap (num_elem, c.num_elem);
00768   }
00769 
00772   iterator begin () const
00773   {
00774     return iterator (*this);
00775   }
00776 
00779   iterator end () const
00780   {
00781     iterator it (*this);
00782 
00783     it.goto_end ();
00784 
00785     return it;
00786   }
00787 
00799   iterator insert (const T & value) 
00800   {
00801     bool node_allocated = false;
00802     Node * tree_node_ptr = static_cast<Node*> (tree.search (value));
00803 
00804     if (tree_node_ptr == NULL)
00805       {
00806      tree_node_ptr = static_cast<Node*>(tree.insert( new Node(value)));
00807      node_allocated = true;
00808       }
00809 
00810     I (tree_node_ptr != NULL);
00811 
00812     try
00813       {
00814      Dnode<T> * list_node_ptr =  new Dnode<T>(value) ;
00815 
00816      tree_node_ptr->key_list.append(list_node_ptr);
00817 
00818      ++tree_node_ptr->num_elem;
00819 
00820      ++num_elem;
00821 
00822      return iterator(this, tree_node_ptr, 
00823                tree_node_ptr->key_list, list_node_ptr);
00824       }
00825     catch (std::bad_alloc)
00826       {
00827      if (node_allocated)
00828        {
00829          tree_node_ptr = static_cast<Node*>(tree.remove (value));
00830      
00831          I (tree_node_ptr != NULL);
00832 
00833          delete tree_node_ptr;
00834        }
00835       
00836      throw;
00837       }
00838   }
00839     
00864   iterator insert (iterator pos, const T & value)
00865   {
00866     Aleph::verify_container_and_iterator (this, pos);
00867 
00868     auto_ptr< Dnode<T> > list_node(new Dnode<T>(value));
00869     try
00870       {
00871      if (*pos == value) // dispara overflow_error si iterador es invalido
00872        {     /* en este caso, debe existir un nodo en el arbol, lo que
00873              evita la busqueda en árbol */
00874          
00875          pos.list_itor.get_current()->insert(list_node.get());
00876          ++static_cast<Node*>(pos.tree_itor.get_current())->num_elem;
00877 
00878          pos.list_itor.set(list_node.release());
00879 
00880          I(KEY(pos.tree_itor.get_current()) == value);
00881        }
00882      else
00883        {
00884          Node * tree_node = static_cast<Node*>(tree.search(value));
00885 
00886          if (tree_node == NULL)
00887            tree_node = static_cast<Node*>(tree.insert(new Node(value)));
00888 
00889          tree_node->key_list.append(list_node.release());
00890          ++tree_node->num_elem;
00891 
00892          pos.tree_itor.reset_to_node (tree_node);
00893          pos.list_itor.reset (&tree_node->key_list);
00894        }
00895 
00896      ++num_elem;
00897       
00898      return pos;
00899       }
00900     catch (std::overflow_error)
00901       {     /* proveniente de if (*pos == value) */
00902      return insert (value); 
00903       }
00904   }
00905 
00923       template <typename Itor>
00924   void insert (Itor beg, const Itor & end)
00925   {
00926     Aleph::verify_iterators (beg, end);
00927 
00928     while (beg != end)
00929       insert(beg++);
00930   }
00931 
00940   size_type erase (const T & value)
00941   {
00942     Node * tree_node = static_cast<Node*> (tree.remove (value));
00943 
00944     if (tree_node == NULL)
00945       return 0;
00946 
00947     const size_t ret_val = tree_node->num_elem;
00948      
00949     delete tree_node;
00950 
00951     num_elem -= ret_val;
00952 
00953     return ret_val;
00954   }
00955 
00969   void erase (iterator pos)
00970   {
00971     Aleph::verify_container_and_iterator (*this, pos);
00972 
00973     Dnode<T> * list_node = pos.list_itor.get_current ();
00974     Node * tree_node = static_cast<Node*> (pos.tree_itor.get_current ());
00975 
00976     I (tree.search (KEY (tree_node)) == tree_node);
00977     I (KEY (tree_node) == list_node->get_data ());
00978 
00979     list_node->del ();
00980     delete list_node;
00981 
00982     --tree_node->num_elem;
00983     --num_elem;
00984 
00985     if (tree_node->num_elem == 0)
00986       {
00987      tree.remove (KEY (tree_node));
00988      delete tree_node;
00989       }
00990   }
00991   
00992 private:
00993 
00994       /* Borra el rango secuencialmente */
00995   iterator delete_range (iterator beg, const iterator & end)
00996   {
00997     while (beg != end)
00998       beg.del ();
00999 
01000     return beg;
01001   }
01002 
01003 public:
01004 
01018   iterator erase (iterator beg, const iterator & end)
01019   {
01020     Aleph::verify_container_and_iterator (*this, beg);
01021     Aleph::verify_iterators (beg, end);
01022 
01023     return delete_range(beg, end);
01024   }
01025 
01027   void clear ()
01028   {
01029     destroyRec (static_cast<Node *> (tree.getRoot ()));
01030     num_elem = 0;
01031   }
01032 };
01033 
01034 
01035     template <typename T>
01036 typename iterator_traits<typename multiset<T>::iterator>::difference_type 
01037 distance (typename multiset<T>::iterator it1, 
01038        typename multiset<T>::iterator it2)
01039 {
01040   typename iterator_traits<typename multiset<T>::iterator>::difference_type
01041     counter = 0;
01042 
01043   
01044   while (it1 != it2)
01045     {
01046       ++counter;
01047       ++it1;
01048     }
01049 
01050   return counter;
01051 }
01052 
01053 } // end namespace Aleph
01054 
01055 # endif // AH_MULTISET_H

Leandro R. León