Eneboo - Documentación para desarrolladores
src/hoard/src/heaplayers/experimental/treap.h
Ir a la documentación de este archivo.
00001 /* -*- C++ -*- */
00002 
00003 #ifndef _TREAP_H_
00004 #define _TREAP_H_
00005 
00006 #include <assert.h>
00007 #include <stdlib.h>
00008 #include <limits.h>
00009 
00010 
00011 // A Cartesian tree.
00012 // adapted from treap code by Bobby Blumofe
00013 
00014 
00015 template <class KEY, class VALUE>
00016 class Treap {
00017 
00018 public:
00019 
00020   class Node {   // A node in the treap.
00021     friend class Treap;
00022     unsigned int priority; //   The priority.
00023     KEY key;      //   The key.
00024     VALUE value;  //   The value.
00025     Node* parent; //   Pointer to parent.
00026     Node* left;   //   Pointer to left child.
00027     Node* right;  //   Pointer to right child.
00028 
00029   public:
00030     // Construct node.
00031     Node (void) : left (NULL), right (NULL) {}
00032 
00033     Node (unsigned int priority_, KEY key_, VALUE value_, Node* parent_)
00034       : priority (priority_), key (key_), value (value_),
00035         parent (parent_), left (NULL), right (NULL) {}
00036     KEY getKey (void) const { return key; }
00037     VALUE getValue (void) const { return value; }
00038   };
00039 
00040   // Construct an empty treap.
00041   Treap (void);
00042 
00043   // Destructor.
00044   ~Treap (void);
00045 
00046   // Return value of key or 0 if not found.
00047   // Return a matching node (or NULL if not found).
00048   Node * lookup (KEY key) const {
00049     return lookup_ (key);
00050   }
00051 
00052   // Return a matching node (or NULL if not found).
00053   Node * lookupGreater (KEY key) const {
00054     return lookupGreater_ (key);
00055   }
00056 
00057   // Set the given key to have the given value.
00058   void insert (Node * n, KEY key, VALUE value, unsigned int priority);
00059 
00060   // Remove entry with given key.
00061   // Remove entry.
00062   Node * remove (Node * node) {
00063 #if 0
00064     // Search for node with given key.
00065     Node* node = lookup_ (key);
00066 #endif
00067     
00068     // If not found, then do nothing.
00069     if (!node)
00070       return NULL;
00071     
00072     // While node is not a leaf...
00073     while (node->left || node->right) {
00074       
00075       // If left child only, rotate right.
00076       if (!node->right)
00077         rotateRight (node);
00078       
00079       // If right child only, rotate left.
00080       else if (!node->left)
00081         rotateLeft (node);
00082       
00083       // If both children,
00084       else {
00085         if (node->left->priority < node->right->priority)
00086           rotateRight (node);
00087         else
00088           rotateLeft (node);
00089       }
00090     }
00091     
00092     // Clip off node.
00093     Node* parent = node->parent;
00094     if (!parent) {
00095       assert (root == node);
00096       root = 0;
00097     }
00098     else {
00099       if (parent->left == node)
00100         parent->left = 0;
00101       else
00102         parent->right = 0;
00103     }
00104     
00105     // Check treap properties.
00106     // assert (heapProperty (root, INT_MIN));
00107     // assert (bstProperty (root, INT_MIN, INT_MAX));
00108     
00109 #if 0
00110     delete node;
00111     return NULL;
00112 #else
00113     // Return the removed node.
00114     
00115     return node;
00116 #endif
00117   }
00118 
00119 
00120   void print (void) const { reallyPrint (root); cout << endl; }
00121 
00122   void reallyPrint (Node * node) const {
00123     if (node == NULL) return;
00124     reallyPrint (node->left);
00125     cout << "[" << node->key << "] ";
00126     reallyPrint (node->right);
00127   }
00128 
00129 
00130 
00131 private:
00132 
00133   Node* root;  // Pointer to root node of treap.
00134 
00135   // Disable copy and assignment.
00136   Treap (const Treap& treap) {}
00137   Treap& operator= (const Treap& treap) { return *this; }
00138 
00139   // Check treap properties.
00140   int heapProperty (Node* node, int lbound) const;
00141   int bstProperty (Node* node, int lbound, int ubound) const;
00142 
00143   // Delete treap rooted at given node.
00144   void deleteTreap (Node* node);
00145 
00146   // Return node with given key or NULL if not found.
00147   Node* lookup_ (KEY key) const;
00148   Node* lookupGreater_ (KEY key) const;
00149   Node* lookupGeq (KEY key, Node * root) const;
00150 
00151   // Perform rotations.
00152   void rotateLeft (Node* node);
00153   void rotateRight (Node* node);
00154 };
00155 
00156 
00157 // Construct an empty treap.
00158 template <class KEY, class VALUE>
00159 Treap<KEY,VALUE>::Treap (void)
00160   : root (0)
00161 {
00162 }
00163 
00164 // Destructor.
00165 template <class KEY, class VALUE>
00166 Treap<KEY,VALUE>::~Treap (void)
00167 {
00168   deleteTreap (root);
00169 }
00170 
00171 // Delete treap rooted at given node.
00172 template <class KEY, class VALUE>
00173 void Treap<KEY,VALUE>::deleteTreap (Node* node)
00174 {
00175   // If empty, nothing to do.
00176   if (!node)
00177     return;
00178 
00179   // Delete left and right subtreaps.
00180   deleteTreap (node->left);
00181   deleteTreap (node->right);
00182 
00183   // Delete root node.
00184   delete node;
00185 }
00186 
00187 // Test heap property in subtreap rooted at node.
00188 template <class KEY, class VALUE>
00189 int Treap<KEY,VALUE>::heapProperty (Node* node, int lbound) const
00190 {
00191   // Empty treap satisfies.
00192   if (!node)
00193     return 1;
00194 
00195   // Check priority.
00196   if (node->priority < lbound)
00197     return 0;
00198 
00199   // Check left subtreap.
00200   if (!heapProperty (node->left, node->priority))
00201     return 0;
00202 
00203   // Check right subtreap.
00204   if (!heapProperty (node->right, node->priority))
00205     return 0;
00206 
00207   // All tests passed.
00208   return 1;
00209 }
00210 
00211 // Test bst property in subtreap rooted at node.
00212 template <class KEY, class VALUE>
00213 int Treap<KEY,VALUE>::bstProperty (Node* node, int lbound, int ubound) const
00214 {
00215   // Empty treap satisfies.
00216   if (!node)
00217     return 1;
00218 
00219   // Check key in range.
00220   if (node->key < lbound || node->key > ubound)
00221     return 0;
00222 
00223   // Check left subtreap.
00224   if (!bstProperty (node->left, lbound, node->key))
00225     return 0;
00226 
00227   // Check right subtreap.
00228   if (!bstProperty (node->right, node->key, ubound))
00229     return 0;
00230 
00231   // All tests passed.
00232   return 1;
00233 }
00234 
00235 // Perform a left rotation.
00236 template <class KEY, class VALUE>
00237 void Treap<KEY,VALUE>::rotateLeft (Node* node)
00238 {
00239   // Get right child.
00240   Node* right = node->right;
00241   assert (right);
00242 
00243   // Give node right's left child.
00244   node->right = right->left;
00245 
00246   // Adjust parent pointers.
00247   if (right->left)
00248     right->left->parent = node;
00249   right->parent = node->parent;
00250 
00251   // If node is root, change root.
00252   if (!node->parent) {
00253     assert (root == node);
00254     root = right;
00255   }
00256 
00257   // Link node parent to right.
00258   else {
00259     if (node->parent->left == node)
00260       node->parent->left = right;
00261     else
00262       node->parent->right = right;
00263   }
00264 
00265   // Put node to left of right.
00266   right->left = node;
00267   node->parent = right;
00268 }
00269 
00270 // Perform a right rotation.
00271 template <class KEY, class VALUE>
00272 void Treap<KEY,VALUE>::rotateRight (Node* node)
00273 {
00274   // Get left child.
00275   Node* left = node->left;
00276   assert (left);
00277 
00278   // Give node left's right child.
00279   node->left = left->right;
00280 
00281   // Adjust parent pointers.
00282   if (left->right)
00283     left->right->parent = node;
00284   left->parent = node->parent;
00285 
00286   // If node is root, change root.
00287   if (!node->parent) {
00288     assert (root == node);
00289     root = left;
00290   }
00291 
00292   // Link node parent to left.
00293   else {
00294     if (node->parent->left == node)
00295       node->parent->left = left;
00296     else
00297       node->parent->right = left;
00298   }
00299 
00300   // Put node to right of left.
00301   left->right = node;
00302   node->parent = left;
00303 }
00304 
00305 // Return node with given key or 0 if not found.
00306 template <class KEY, class VALUE>
00307 Treap<KEY,VALUE>::Node* Treap<KEY,VALUE>::lookup_ (KEY key) const
00308 {
00309   // Start at the root.
00310   Node* node = root;
00311 
00312   // While subtreap rooted at node not empty...
00313   while (node) {
00314 
00315     // If found, then return value.
00316     if (key == node->key)
00317       return node;
00318 
00319     // Otherwise, search left or right subtreap.
00320     else if (key < node->key)
00321       node = node->left;
00322     else
00323       node = node->right;
00324   }
00325 
00326   // Return.
00327   return node;
00328 }
00329 
00330 
00331 template <class KEY, class VALUE>
00332 Treap<KEY,VALUE>::Node* Treap<KEY,VALUE>::lookupGreater_ (KEY key) const
00333 {
00334   return lookupGeq (key, root);
00335 }
00336 
00337 
00338 // Return node with greater or equal key or 0 if not found.
00339 template <class KEY, class VALUE>
00340 Treap<KEY,VALUE>::Node* Treap<KEY,VALUE>::lookupGeq (KEY key, Node * rt) const
00341 {
00342   Node * bestSoFar = NULL;
00343 
00344   // Start at the root.
00345   Node* node = rt;
00346 
00347   // While subtreap rooted at node not empty...
00348   while (node) {
00349 
00350     // If exact match found, then return value.
00351     if (key == node->key)
00352       return node;
00353 
00354     // Move right -- this node is too small.
00355     if (node->key < key)
00356       node = node->right;
00357     
00358     // Otherwise, this one's pretty good;
00359     // look for a better match.
00360     else {
00361       if ((bestSoFar == NULL) || (bestSoFar->key > node->key))
00362         bestSoFar = node;
00363       node = node->left;
00364     }
00365   }
00366 
00367   // Return.
00368   return bestSoFar;
00369 }
00370 
00371 
00372 // Set the given key to have the given value.
00373 template <class KEY, class VALUE>
00374 void Treap<KEY,VALUE>::insert (Treap<KEY,VALUE>::Node * n, KEY key, VALUE value, unsigned int priority)
00375 {
00376 
00377   //  print();
00378 
00379   // 0 is not a valid value.
00380   assert (value != 0);
00381 
00382   // Start at the root.
00383   Node* parent = 0;
00384   Node* node = root;
00385 
00386 
00387   // While subtreap rooted at node not empty...
00388   while (node) {
00389 
00390 #if 0
00391     // If found, then update value and done.
00392     if (key == node->key) {
00393       node->value = value;
00394       return;
00395     }
00396 #endif
00397 
00398     // Otherwise, search left or right subtreap.
00399     parent = node;
00400 
00401 
00402     if (key < node->key)
00403       node = node->left;
00404     else
00405       node = node->right;
00406   }
00407 
00408 
00409   // Not found, so create new node.
00410   // EDB was
00411   // node = new Node (lrand48(), key, value, parent);
00412   node = new (n) Node (priority, key, value, parent);
00413   // node = new Node (priority, key, value, parent);
00414 
00415   // If the treap was empty, then new node is root.
00416   if (!parent)
00417     root = node;
00418 
00419   // Otherwise, add node as left or right child.
00420   else if (key < parent->key)
00421     parent->left = node;
00422   else
00423     parent->right = node;
00424 
00425   // While heap property not satisfied...
00426   while (parent && parent->priority > node->priority) {
00427 
00428     // Perform rotation.
00429     if (parent->left == node)
00430       rotateRight (parent);
00431     else
00432       rotateLeft (parent);
00433 
00434     // Move up.
00435     parent = node->parent;
00436   }
00437 
00438   // print();
00439 
00440   // Check treap properties.
00441   // assert (heapProperty (root, INT_MIN));
00442   // assert (bstProperty (root, INT_MIN, INT_MAX));
00443 }
00444 
00445 
00446 
00447 #endif // _TREAP_H_
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Propiedades Amigas 'defines'