tpl_treap.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_TREAP_H
00045 # define TPL_TREAP_H
00046 
00047 # include <gsl/gsl_rng.h> 
00048 # include <ahFunction.H>
00049 # include <treapNode.H>
00050 # include <tpl_binNodeUtils.H>
00051 # include <ran_array.h>
00052 
00053 using namespace Aleph;
00054 
00055 namespace Aleph
00056 {
00057 
00082     template <template <typename> class NodeType, typename Key, class Compare>
00083 class Gen_Treap
00084 {
00085 
00086 public:
00088   typedef NodeType<Key> Node;
00089 
00090   
00091   private:
00092 
00093   Node        head;
00094   Node *      head_ptr;
00095   Node *&     tree_root;
00096   gsl_rng * r;
00097   public:
00098 
00100   Gen_Treap() : head_ptr(&head), tree_root(RLINK(head_ptr)), r(NULL)
00101   {
00102     PRIO(head_ptr) = Min_Priority;
00103 
00104     r = gsl_rng_alloc (gsl_rng_mt19937);
00105 
00106     if (r == NULL)
00107       throw std::bad_alloc();
00108 
00109     gsl_rng_set(r, time(NULL) % gsl_rng_max(r));
00110   }
00111 
00113   ~Gen_Treap() 
00114   {
00115     if (r != NULL)
00116       gsl_rng_free(r);
00117   }
00118 
00120   gsl_rng * gsl_rng_object() { return r;}
00121 
00123   Node *& getRoot() { return tree_root; }
00124 
00126   Node * search(const Key & key)
00127   {
00128     Node* ret_val = searchInBinTree<Node, Compare>(tree_root, key);
00129 
00130     return ret_val == Node::NullPtr ? NULL : ret_val;
00131   }
00132 
00133   private:
00134 
00135   static Node * insert(Node * root, Node * p)
00136   {
00137     if (root == Node::NullPtr)
00138       return p;
00139 
00140     Node * insertion_result = NULL;
00141     if (Compare() (KEY(p), KEY(root))) 
00142       {
00143         insertion_result = insert(LLINK(root), p);
00144 
00145         if (insertion_result == Node::NullPtr)
00146           return Node::NullPtr;
00147 
00148         LLINK(root) = insertion_result;
00149 
00150         if (PRIO(insertion_result) < PRIO(root))
00151           return rotate_to_right(root);
00152         else
00153           return root;
00154       }
00155     else if (Compare() (KEY(root), KEY(p)))
00156       {
00157         insertion_result = insert(RLINK(root), p);
00158 
00159         if (insertion_result == Node::NullPtr)
00160           return Node::NullPtr;
00161 
00162         RLINK(root) = insertion_result;
00163 
00164         if (PRIO(insertion_result) < PRIO(root))
00165           return rotate_to_left(root);
00166         else
00167           return root;
00168       }
00169 
00170     return Node::NullPtr;
00171   }
00172 
00173   public:
00174 
00183   Node * insert(Node * p)
00184   {
00185 
00186     I(p != Node::NullPtr);
00187 
00188     PRIO(p) = gsl_rng_get(r);
00189 
00190     Node * result = insert(tree_root, p);
00191 
00192     if (result == Node::NullPtr)
00193       return NULL;
00194 
00195     tree_root = result;
00196 
00197     return p;  
00198   }
00208   Node * remove(const Key & key)
00209   {
00210     Node ** pp = &RLINK(head_ptr);
00211     Node * p = tree_root;
00212     while (p != Node::NullPtr)
00213       if (Compare() (key, KEY(p)))
00214         {
00215           pp = &LLINK(p);
00216           p  = LLINK(p);
00217         }
00218       else if (Compare() (KEY(p), key))
00219         {
00220           pp = &RLINK(p);
00221           p  = RLINK(p);
00222         }
00223       else
00224         break;
00225 
00226     if (p == Node::NullPtr)
00227       return NULL; // clave no fue encontrada
00228 
00229     while (not (LLINK(p) == Node::NullPtr and RLINK(p) == Node::NullPtr))
00230       if (PRIO(LLINK(p)) < PRIO(RLINK(p)))
00231         {
00232           *pp = rotate_to_right(p);
00233           pp  = &RLINK(*pp);
00234         }
00235       else
00236         {
00237           *pp = rotate_to_left(p);
00238           pp  = &LLINK(*pp);
00239         }
00240 
00241     *pp = Node::NullPtr;
00242 
00243     p->reset();
00244 
00245     return p;
00246   }
00247 };
00248 
00271     template <typename Key, class Compare = Aleph::less<Key> >
00272 class Treap : public Gen_Treap<TreapNode, Key, Compare>
00273     { /* empty */ };
00274 
00297     template <typename Key, class Compare = Aleph::less<Key> >
00298 class Treap_Vtl : public Gen_Treap<TreapNodeVtl, Key, Compare>
00299     { /* empty */ };
00300 
00301 } // end namespace Aleph
00302 # endif // TPL_TREAP_H
00303 

Leandro R. León