tpl_treapRk.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 # ifndef TPL_TREAPRK_H
00044 # define TPL_TREAPRK_H
00045 
00046 # include <gsl/gsl_rng.h>
00047 # include <ahFunction.H>
00048 # include <tpl_binNodeUtils.H>
00049 # include <tpl_binNodeXt.H>
00050 # include <ran_array.h>
00051 # include <treapNode.H>
00052 
00053 using namespace Aleph;
00054 
00055 namespace Aleph {
00056 
00057 class TreapRkNode_Data
00058 {
00059   long priority; 
00060 
00061   long count;
00062 
00063 public:
00064 
00065   TreapRkNode_Data () : priority (Max_Priority), count (1) 
00066   { 
00067     /* empty */ 
00068   }
00069 
00070   TreapRkNode_Data (SentinelCtor) 
00071     : priority (Max_Priority), count (0) 
00072   { 
00073     /* empty */ 
00074   }
00075 
00076   long & getPriority () { return priority; }
00077 
00078   long & getCount () { return count; }
00079 
00080   void reset () 
00081   {
00082     priority = Max_Priority; 
00083     count = 1;
00084   }
00085 };
00086 
00087 DECLARE_BINNODE_SENTINEL (Treap_Rk_Node, 80, TreapRkNode_Data);
00088 
00128     template <template <class> class NodeType, class Key, class Compare>
00129 class Gen_Treap_Rk
00130 {
00131 public:
00132 
00134   typedef NodeType<Key> Node;
00135 
00136 private:
00137 
00138   Node      head;
00139   Node *    head_ptr;
00140   Node *&   tree_root;
00141   Compare   cmp;
00142   gsl_rng * r;
00143 
00144 public:
00145 
00147   Gen_Treap_Rk () : head_ptr(&head), tree_root(RLINK(head_ptr)), r(NULL)
00148   {
00149     PRIO (head_ptr) = Min_Priority;
00150 
00151       r = gsl_rng_alloc (gsl_rng_mt19937);
00152 
00153       if (r == NULL)
00154      throw std::bad_alloc();
00155 
00156       gsl_rng_set(r, time(NULL) % gsl_rng_max(r));
00157   }
00158 
00159   ~Gen_Treap_Rk ()
00160   {
00161     if (r != NULL)
00162       gsl_rng_free(r);
00163   }
00164 
00170   void swap (Gen_Treap_Rk & tree)
00171   {
00172     Aleph::swap (LLINK (head_ptr), LLINK (tree.head_ptr) );
00173     Aleph::swap (RLINK (head_ptr), RLINK (tree.head_ptr) );
00174     Aleph::swap (head_ptr, tree.head_ptr);
00175     Aleph::swap (tree_root, tree.tree_root);
00176   }
00177 
00179   Node *& getRoot () { return tree_root; }
00180 
00182   Node * search (const Key & key)
00183   {
00184     Node* ret_val = searchInBinTree<Node, Compare> (tree_root, key);
00185 
00186     return ret_val == Node::NullPtr ? NULL : ret_val;
00187   }
00188 
00189 private:
00190 
00191   Node * insert (Node * root, Node * p) 
00192   {
00193     if (root == Node::NullPtr)
00194       return p;
00195 
00196     Node * insertion_result;
00197 
00198     if (cmp (KEY (p), KEY (root) ) )
00199       {
00200         insertion_result = insert (LLINK (root), p);
00201 
00202         if (insertion_result == Node::NullPtr)
00203           return Node::NullPtr;
00204 
00205      ++COUNT (root);
00206         LLINK (root) = insertion_result;
00207 
00208         if (PRIO (insertion_result) < PRIO (root) )
00209           return rotate_to_right_xt (root);
00210 
00211      return root;
00212       }
00213     else if (cmp (KEY (root), KEY (p) ) )
00214       {
00215         insertion_result = insert (RLINK (root), p);
00216 
00217         if (insertion_result == Node::NullPtr)
00218           return Node::NullPtr;
00219 
00220      ++COUNT (root);
00221         RLINK (root) = insertion_result;
00222 
00223         if (PRIO (insertion_result) < PRIO (root) )
00224           return rotate_to_left_xt (root);
00225 
00226      return root;
00227       }
00228 
00229     return Node::NullPtr;
00230   }
00231 
00232 public:
00233 
00242   Node * insert (Node * p)
00243   {
00244     I (p not_eq Node::NullPtr);
00245 
00246     PRIO(p) = gsl_rng_get(r);
00247 
00248     Node * result = insert (tree_root, p);
00249 
00250     if (result == Node::NullPtr)
00251       return NULL;
00252 
00253     tree_root = result;
00254 
00255     return p;  
00256   }
00257 
00258 private:
00259 
00260   static Node * join_treaps (Node * t1, Node * t2)
00261   {
00262     if (t1 == Node::NullPtr)
00263       return t2;
00264 
00265     if (t2 == Node::NullPtr)
00266       return t1;
00267 
00268     if (PRIO (t1) < PRIO (t2) )
00269       {
00270      COUNT (t1) += COUNT (t2);
00271      RLINK (t1) = join_treaps (RLINK (t1), t2);
00272      
00273      return t1;
00274       }
00275     else
00276       {
00277      COUNT (t2) += COUNT (t1);
00278      LLINK (t2) = join_treaps (t1, LLINK (t2) );
00279      
00280      return t2;
00281       }
00282   }
00283 
00284   Node * remove (Node *& root, const Key & key)
00285   {
00286     if (root == Node::NullPtr)
00287       return Node::NullPtr;
00288 
00289     Node * ret_val;
00290 
00291     if (cmp (key, KEY (root) ))
00292       ret_val = remove (LLINK (root), key);
00293     else if (cmp (KEY (root), key) )
00294       ret_val = remove (RLINK (root), key);
00295     else
00296       {
00297      ret_val = root;
00298      root = join_treaps (LLINK (root), RLINK (root) );
00299      
00300      return ret_val;
00301       }
00302 
00303     if (ret_val == Node::NullPtr)
00304       return Node::NullPtr;
00305       
00306     --COUNT (root);
00307 
00308     return ret_val;
00309   }
00310 
00311 public:
00312 
00322   Node * remove (const Key & key)
00323   {
00324     Node * ret_val = remove (tree_root, key);
00325 
00326     if (ret_val == Node::NullPtr)
00327       return NULL;
00328 
00329     ret_val->reset ();
00330 
00331     return ret_val;
00332   } 
00333 
00349   Node * remove (const size_t & beg, const size_t & end)
00350   {
00351     if (beg > end or end > COUNT (tree_root))
00352       throw std::range_error ("remove of TreapRk out of range");
00353 
00354     Node * before_beg, * after_end;
00355 
00356     Node * ret_val = tree_root;
00357 
00358     split_pos_rec (ret_val, end + 1, ret_val, after_end);
00359 
00360     split_pos_rec (ret_val, beg, before_beg, ret_val);
00361 
00362     tree_root = join_treaps(before_beg, after_end);
00363 
00364     return ret_val;
00365   }
00366   
00377   Node * select (const size_t & i)
00378   {
00379     return Aleph::select(tree_root, i); 
00380   }
00381 
00383   size_t size () const 
00384   {
00385     return COUNT(tree_root);
00386   }
00387 
00400   size_t position (const Key & key)
00401   {
00402     Node * p;
00403 
00404     const long ret_val = Aleph::inorder_position(tree_root, key, p);
00405 
00406     IG(KEY(p) == key, ret_val >= 0);
00407 
00408     return ret_val;
00409   }
00410 
00419   class Iterator
00420   {
00421   protected:
00422     
00423     mutable Gen_Treap_Rk * tree_ptr; 
00424     mutable Node * curr;
00425     mutable int    curr_pos;
00426 
00427   private:
00428 
00429     bool pos_updated () const
00430     {
00431       return curr_pos not_eq -2;
00432     }
00433 
00434     bool curr_updated () const
00435     {
00436       return curr not_eq NULL;
00437     }
00438 
00439     bool is_updated () 
00440     {
00441       return pos_updated () and curr_updated ();
00442     }
00443 
00444     void update_pos () const
00445     {
00446       I (curr not_eq NULL);
00447 
00448       curr_pos = 
00449      Aleph::inorder_position (tree_ptr->getRoot (), KEY (curr), curr);
00450     }
00451 
00452     void update_curr () const
00453     {
00454       I (curr_pos not_eq -2);
00455 
00456       if (curr_pos == -1 or curr_pos == COUNT (tree_ptr->getRoot () ))
00457      return;
00458 
00459       curr = Aleph::select (tree_ptr->getRoot (), curr_pos);
00460     }
00461 
00462   public:
00463 
00465     Iterator () : tree_ptr(NULL), curr(NULL), curr_pos(-2)
00466     {
00467       /* empty */ 
00468     }
00469 
00471     Iterator (Gen_Treap_Rk & __tree) 
00472       : tree_ptr(&__tree), curr(NULL), curr_pos(0)
00473     {
00474       // Empty
00475     }
00476 
00479     Iterator (Gen_Treap_Rk & __tree, Node * __curr)
00480       : tree_ptr(&__tree), curr(__curr), curr_pos(-2)
00481     {
00482       // empty
00483     }
00484 
00486     Iterator (Gen_Treap_Rk & __tree, const size_t & pos)
00487       : tree_ptr(&__tree), curr(NULL), curr_pos(pos)
00488     {
00489       // empty
00490     }
00491 
00493     Iterator (const Iterator & itor)
00494       : tree_ptr(itor.tree_ptr), curr(itor.curr), curr_pos(itor.curr_pos)
00495     {
00496       // Empty
00497     }
00498 
00500     Iterator & operator = (const Iterator & itor)
00501     {
00502       if (this == &itor)
00503      return *this;
00504 
00505       tree_ptr = itor.tree_ptr;
00506       curr = itor.curr;
00507       curr_pos = itor.curr_pos;
00508 
00509       return *this;
00510     }
00511 
00513     void reset_first ()
00514     {
00515       curr = NULL;
00516       curr_pos = 0;
00517     }
00518 
00520     void reset_last ()
00521     {
00522       curr = NULL;
00523       curr_pos = COUNT (tree_ptr->getRoot () ) - 1;
00524     }
00525 
00532     void reset_to_key (const Key & key)
00533     {
00534       curr_pos = Aleph::inorder_position (tree_ptr->getRoot (), key, curr);
00535     }
00536 
00543     void reset_to_node (Node * node)
00544     {
00545       curr = node;
00546       curr_pos = -2;
00547     }
00548 
00550     void reset_to_pos (size_t pos)
00551     {
00552       curr = NULL;
00553       curr_pos = pos;
00554     }
00555 
00557     Node * get_current () const
00558     {
00559       if (not curr_updated ())
00560      update_curr ();
00561 
00562       return curr; 
00563     }
00564 
00575     size_t get_current_position () const
00576       throw (std::exception, std::underflow_error, std::overflow_error)
00577     {
00578       if (not pos_updated ())
00579      update_pos ();
00580 
00581       if (curr_pos < -1 )
00582      throw std::range_error ("TreapRk iterator has not current");
00583      
00584       if (curr_pos > COUNT (tree_ptr->getRoot () ) )
00585      throw std::range_error ("TreapRk iterator has not current");
00586 
00587       return curr_pos;
00588     }
00589 
00592     bool has_current () const
00593     {
00594       if (not pos_updated ())
00595      update_pos ();
00596 
00597       return curr_pos >= 0 and curr_pos < COUNT (tree_ptr->getRoot ());
00598     }
00599 
00601     void prev () throw (std::exception, std::underflow_error)
00602     {
00603       if (not has_current () )
00604      throw std::underflow_error ("TreapRk iterator has not current");
00605 
00606       --curr_pos;
00607       curr = NULL;
00608     }
00609 
00611     void next () throw (std::exception, std::overflow_error)
00612     {
00613       if (not has_current () )
00614      throw std::underflow_error ("TreapRk iterator has not current");
00615 
00616       ++curr_pos;
00617       curr = NULL;
00618     }
00619 
00622     Node * del ()
00623     {
00624       if (not has_current () )
00625      throw std::underflow_error ("TreapRk iterator has not current");
00626 
00627       if (not curr_updated ())
00628      update_curr ();
00629 
00630       Node * ret_val = tree_ptr->remove (KEY (curr) );
00631       
00632       curr = NULL;
00633 
00634       return ret_val;
00635     }
00636 
00638     bool operator == (const Iterator & itor) const
00639     {
00640       if (pos_updated () and itor.pos_updated ())
00641      return curr_pos == itor.curr_pos;
00642 
00643       if (curr_updated () and itor.curr_updated ())
00644      return curr == itor.curr;
00645 
00646       if (not pos_updated ())
00647      {
00648        update_pos ();
00649        return curr_pos == itor.curr_pos;
00650      }
00651 
00652       itor.update_pos ();
00653 
00654       return curr_pos == itor.curr_pos;
00655     }
00656   
00658     bool operator != (const Iterator & itor) const
00659     {
00660       return not (*this == itor);
00661     }
00662 
00663     bool verify (Gen_Treap_Rk * r) const
00664     {
00665       return tree_ptr->getRoot () == r->getRoot ();
00666     }
00667 
00668     bool verify (const Iterator & it) const
00669     {
00670       return tree_ptr->getRoot () == it.tree_ptr->getRoot ();
00671     }
00672   }; // end class Iterator
00673 };
00674 
00710     template <class Key, class Compare = Aleph::less<Key> >
00711 class Treap_Rk : public Gen_Treap_Rk<Treap_Rk_Node, Key, Compare>
00712     { /* empty */ };
00713 
00749     template <class Key, class Compare = Aleph::less<Key> >
00750 class Treap_Rk_Vtl : public Gen_Treap_Rk<Treap_Rk_NodeVtl, Key, Compare>
00751     { /* empty */ };
00752 
00753 } // end namespace Aleph
00754 
00755 # endif // TPL_TREAPRK_H

Leandro R. León