tpl_dynMapTree.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 # ifndef TPL_DYNMAPTREE_H
00045 # define TPL_DYNMAPTREE_H
00046 
00047 # include <tpl_binNodeUtils.H>
00048 
00049 using namespace Aleph;
00050 
00051 namespace Aleph {
00052 
00075     template <
00076       template <typename /* Key */, class /* Compare */> class Tree, 
00077       typename Key, 
00078       typename Range,
00079       class Compare = Aleph::less<Key>      
00080       > 
00081 class DynMapTree
00082 {
00083   Tree<Key, Compare> tree; 
00084   size_t             num_nodes; 
00085   struct Node : public Tree<Key, Compare>::Node 
00086   {
00087 
00088     friend class DynMapTree<Tree, Key, Range, Compare>;
00089 
00090     Range data;
00091 
00092     Node() { /* Empty */ }
00093 
00094     Node(const Key & _key) : Tree<Key, Compare>::Node(_key) { /* empty */ }
00095 
00096     Range & get_data() { return data; } 
00097   };
00098   class Proxy
00099   {
00100     DynMapTree & tree;
00101     const Key  & key;
00102     Node       * node;
00103 
00104   public:
00105 
00106     Proxy(DynMapTree & _tree, const Key &_key) : tree(_tree), key(_key)
00107     {
00108       node = static_cast<Node*>(tree.tree.search(key));
00109     }
00110 
00111     Proxy & operator = (const Range & data)
00112     {
00113       if (node == NULL)
00114         {
00115           node = static_cast<Node*>(tree.tree.insert(new Node (key)));
00116 
00117           tree.num_nodes++;
00118         }
00119 
00120       node->get_data() = data;
00121       
00122       return *this;
00123     }
00124 
00125     Proxy& operator = (const Proxy & proxy)
00126     {
00127       if (this == &proxy)
00128         return *this;
00129 
00130       if (proxy.node == NULL)
00131         throw std::domain_error("key not found");;
00132 
00133       if (&tree == &proxy.tree and key == proxy.key)
00134         return *this; // se trata del mismo elemento del mapeo
00135 
00136       if (node == NULL)
00137         {
00138           node = static_cast<Node*>(tree.tree.insert(new Node (key)));
00139 
00140           tree.num_nodes++;         
00141         }
00142       
00143       node->get_data() = proxy.node->get_data();
00144       
00145       return *this;
00146     }
00147 
00148     operator Range & () const
00149     {
00150       if (node == NULL)
00151         throw std::domain_error("key not found");;
00152 
00153       return node->get_data();
00154     }    
00155   };
00156 
00157 public:
00158 
00160   const size_t & size() const { return num_nodes; }
00162   bool is_empty() const { return size() == 0; }
00164   DynMapTree() : num_nodes(0) { /* empty */ }
00165 
00167   DynMapTree(DynMapTree & src_tree) : num_nodes(src_tree.num_nodes) 
00168   { 
00169     Node * src_root = static_cast<Node*>(src_tree.tree.getRoot()); 
00170 
00171     try 
00172       {
00173 
00174 
00175         tree.getRoot() = copyRec(src_root);
00176 
00177       }
00178     catch (...) // hubo falla 
00179       {
00180         num_nodes = 0;
00181         throw;
00182       }
00183 
00184   }
00185 
00187   virtual ~DynMapTree() 
00188   {
00189     if (num_nodes > 0)
00190       destroyRec(tree.getRoot());
00191   }
00193   DynMapTree & operator = (DynMapTree & src_tree)
00194   {
00195     if (this == &src_tree)
00196       return *this;
00197 
00198     Node * src_root = static_cast<Node*>(src_tree.tree.getRoot());
00199     Node * old_root = static_cast<Node*>(tree.getRoot());
00200 
00201     tree.getRoot() = copyRec(src_root);
00202     num_nodes      = src_tree.num_nodes;
00203 
00204     destroyRec(old_root);
00205 
00206     return *this;
00207   }
00219   size_t insert(const Key & key, const Range & data)
00220   {
00221     Node * node = new Node (key);
00222     node->data = data;
00223 
00224     if (tree.insert(node) == NULL)
00225       {
00226         delete node;
00227         return num_nodes;
00228       }
00229 
00230     return ++num_nodes;
00231   }
00240   size_t remove(const Key & key)
00241   {
00242     Node * node = static_cast<Node*>(tree.remove(key));
00243 
00244     if (node == NULL)
00245       return num_nodes;
00246 
00247     delete node;
00248 
00249     return --num_nodes;
00250   }
00252   void empty()
00253   {
00254     num_nodes = 0;
00255     destroyRec(static_cast<Node*>(tree.getRoot()));
00256   }
00258   bool test_key(const Key & key)
00259   {
00260     Node * node = static_cast<Node*>(tree.search(key));
00261 
00262     return node != NULL;
00263   }
00264 
00274   Range * test(const Key & key)
00275   {
00276     Node * node = static_cast<Node*>(tree.search(key));
00277 
00278     return node != NULL ? &(node->get_data()) : NULL;
00279   }
00280   Proxy operator [] (const Key & key) const 
00281     Exception_Prototypes(std::domain_error)
00282   {
00283     return Proxy(*this, key);
00284   }
00285 
00286   Proxy operator [] (const Key & key) 
00287     Exception_Prototypes(std::domain_error)
00288   {
00289     return Proxy(*this, key);
00290   }
00292   size_t internal_path_length() 
00293   {
00294     return Aleph::internal_path_length(tree.getRoot()); 
00295   }
00296 
00298   size_t height() { return computeHeightRec(tree.getRoot()); }
00300   void for_each_in_preorder(void (*visitFct)(Node*, int, int))
00301   {
00302     Node * root = static_cast<Node*>(tree.getRoot());
00303 
00304     preOrderRec(root, visitFct); 
00305   }
00306 
00308   void for_each_in_inorder(void (*visitFct)(Node*, int, int))
00309   {
00310     Node * root = static_cast<Node*>(tree.getRoot());
00311 
00312     inOrderRec(root, visitFct);
00313   }
00314 
00316   void for_each_in_postorder(void (*visitFct)(Node*, int, int))
00317   {
00318     Node * root = static_cast<Node*>(tree.getRoot());
00319 
00320     postOrderRec(root, visitFct);
00321   } 
00322 
00324   void for_each(void (*visitFct)(Node*, int, int))
00325   {
00326     for_each_in_inorder(visitFct);
00327   }
00329   typedef Node Node_Type;
00330 
00332   typedef Tree<Key, Compare> Tree_Type;
00334   const Key & get_key(Node_Type * p)
00335   {
00336     return p->get_key();
00337   }
00338 
00340   Range & get_data(Node_Type * p)
00341   {
00342     return p->get_data();
00343   }
00344 };
00345 
00346 } // end namespace Aleph
00347 
00348 # include <tpl_binTree.H>
00349 # include <tpl_avl.H>
00350 # include <tpl_rb_tree.H>
00351 # include <tpl_rand_tree.H>
00352 # include <tpl_treap.H>
00353 # include <tpl_splay_tree.H>
00354 
00355 namespace Aleph {
00362     template <typename Key, typename Type, class Compare = Aleph::less<Key> >
00363 class DynMapBinTree : public DynMapTree<BinTree, Key, Type, Compare>
00364     { /* Empty */ };
00365 
00372     template <typename Key, typename Type, class Compare = Aleph::less<Key> >
00373 class DynMapAvlTree : public DynMapTree<Avl_Tree, Key, Type, Compare>
00374     { /* empty */ };
00381     template <typename Key, typename Type, class Compare = Aleph::less<Key> >
00382 class DynMapRbTree : public DynMapTree<Rb_Tree, Key, Type, Compare>
00383     { /* empty */ };
00384 
00392     template <typename Key, typename Type, class Compare = Aleph::less<Key> >
00393 class DynMapRandTree : public DynMapTree<Rand_Tree, Key, Type, Compare>
00394     { /* empty */ };
00395 
00402     template <typename Key, typename Type, class Compare = Aleph::less<Key> >
00403 class DynMapTreap : public DynMapTree<Treap, Key, Type, Compare>
00404     { /* empty */ };
00405 
00412     template <typename Key, typename Type, class Compare = Aleph::less<Key> >
00413 class DynMapSplayTree : public DynMapTree<Splay_Tree, Key, Type, Compare>
00414     { /* empty */ };
00415 
00416 } // end namespace Aleph
00417 
00418 # endif /* TPL_DYNMAPTREE_H */
00419 

Leandro R. León