varden

skiplist source

Feb 11th, 2016
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.19 KB | None | 0 0
  1. #include "SkipList.h"
  2.  
  3. template <class Key, class Obj>
  4. SkipList<Key, Obj>::SkipList(float p, int m, Key* k)
  5. {
  6.     curHeight = 1;
  7.     maxHeight = m;
  8.     probability = p;
  9.  
  10.     //create head with maximum height
  11.     head = new SkipNode<Key, Obj>(maxHeight);
  12.     //create tail with maximum height
  13.     tail = new SkipNode<Key, Obj>(k, (Obj*)NULL, maxHeight);
  14.     //attach all of head's pointers to the tail
  15.     for (int x = 1; x <= maxHeight; x++)
  16.     {
  17.         head->forwardNodes[x] = tail;
  18.     }
  19. }
  20.  
  21. template <class Key, class Obj>
  22. SkipList<Key, Obj>::~SkipList()
  23. {
  24.     SkipNode<Key, Obj>* tmp;
  25.     SkipNode<Key, Obj>* nxt;
  26.     tmp = head;
  27.     //go through all base-level nodes and remove them
  28.     while (tmp)
  29.     {
  30.         nxt = tmp->forwardNodes[1];
  31.         delete tmp;
  32.         tmp = nxt;
  33.     }
  34. }
  35.  
  36. template <class Key, class Obj>
  37. bool SkipList<Key, Obj>::insert(Key* k, Obj* o)
  38. {
  39.     int lvl = 0, h = 0;
  40.     SkipNode<Key, Obj>** updateVec =
  41.         new SkipNode<Key, Obj>*[maxHeight + 1];
  42.     SkipNode<Key, Obj>* tmp = head;
  43.     Key* cmpKey;
  44.  
  45.     //find the right spot for new node on each level
  46.     //starting from the highest level, go over each level
  47.     for (h = curHeight; h >= 1; h--)
  48.     {
  49.         //get key of next node on height h
  50.         cmpKey = tmp->forwardNodes[h]->getKey();
  51.         //compare and go further until you find a node with key greater than new item's
  52.         //we're comparing key of next node, while keeping preceding node in tmp
  53.         while (*cmpKey < *k)
  54.         {
  55.             tmp = tmp->forwardNodes[h];
  56.             cmpKey = tmp->forwardNodes[h]->getKey();
  57.         }
  58.         //vector of all preceding nodes
  59.         updateVec[h] = tmp;
  60.     }
  61.  
  62.     //we've got preceding node on base level in tmp, go 1 forward
  63.     tmp = tmp->forwardNodes[1];
  64.     cmpKey = tmp->getKey();
  65.  
  66.     //if duplicate, don't insert the new node
  67.     if (*cmpKey == *k)
  68.     {
  69.         return false;
  70.     }
  71.     else //insert the node
  72.     {
  73.         //generate height of new node
  74.         lvl = generateHeight();
  75.         if (lvl > curHeight) //if it's greater than current maximum height, update the head
  76.         {
  77.             for (int i = curHeight + 1; i <= lvl; i++)
  78.                 updateVec[i] = head;
  79.             curHeight = lvl;
  80.         }
  81.         //insert the new element on all levels up to his height
  82.         tmp = new SkipNode<Key, Obj>(k, o, lvl);
  83.         for (int i = 1; i <= lvl; i++)
  84.         {
  85.             tmp->forwardNodes[i] = updateVec[i]->forwardNodes[i];
  86.             updateVec[i]->forwardNodes[i] = tmp;
  87.         }
  88.     }
  89.     return true;
  90. }
  91.  
  92. template <class Key, class Obj>
  93. bool SkipList<Key, Obj>::remove(Key* k)
  94. {
  95.     SkipNode<Key, Obj>** updateVec =
  96.         new SkipNode<Key, Obj>*[maxHeight + 1];
  97.     SkipNode<Key, Obj>* tmp = head;
  98.     Key* cmpKey;
  99.  
  100.     //find the nodes preceding this node on all levels
  101.     for (int h = curHeight; h > 0; h--)
  102.     {
  103.         cmpKey = tmp->forwardNodes[h]->getKey();
  104.         while (*cmpKey < *k)
  105.         {
  106.             tmp = tmp->forwardNodes[h];
  107.             cmpKey = tmp->forwardNodes[h]->getKey();
  108.         }
  109.         //vector of all preceding nodes
  110.         updateVec[h] = tmp;
  111.     }
  112.     //we've got preceding node on base level in tmp, go 1 forward
  113.     tmp = tmp->forwardNodes[1];
  114.     cmpKey = tmp->getKey();
  115.  
  116.     //delete the node
  117.     if (*cmpKey == *k)
  118.     {
  119.         //on all levels of list
  120.         for (int i = 1; i <= curHeight; i++)
  121.         {
  122.             //if level exceeds height of this node, break
  123.             if (updateVec[i]->forwardNodes[i] != tmp)
  124.                 break;
  125.             //attach preceding node to the next one
  126.             updateVec[i]->forwardNodes[i] = tmp->forwardNodes[i];
  127.         }
  128.         //delete this node
  129.         delete tmp;
  130.  
  131.         //calculate new height of list (if this node was the highest)
  132.         while ((curHeight > 1) &&
  133.             ((head->forwardNodes[curHeight]->getKey() == tail->getKey())))
  134.             curHeight--;
  135.         return true;
  136.     }
  137.     else
  138.     {
  139.         return false;
  140.     }
  141. }
  142.  
  143. template <class Key, class Obj>
  144. Obj* SkipList<Key, Obj>::retrieve(Key* k)
  145. {
  146.     int h = 0;
  147.     //SkipNode<Key, Obj>** updateVec = new SkipNode<Key, Obj>*[maxHeight + 1];
  148.     SkipNode<Key, Obj>* tmp = head;
  149.     Key* cmpKey;
  150.  
  151.     //starting from the top level, find the node
  152.     for (h = curHeight; h >= 1; h--)
  153.     {
  154.         cmpKey = tmp->forwardNodes[h]->getKey();
  155.         while (*cmpKey < *k)
  156.         {
  157.             tmp = tmp->forwardNodes[h];
  158.             cmpKey = tmp->forwardNodes[h]->getKey();
  159.         }
  160.     }
  161.  
  162.     //we've got preceding node on base level in tmp, go 1 forward
  163.     tmp = tmp->forwardNodes[1];
  164.     cmpKey = tmp->getKey();
  165.     if (*cmpKey == *k)
  166.         return tmp->getObj();
  167.     else
  168.         return (SkipNode<Key, Obj>*) NULL;
  169. }
  170.  
  171. template <class Key, class Obj>
  172. int SkipList<Key, Obj>::generateHeight()
  173. {
  174.     //random seed
  175.     srand(time(NULL));
  176.     //start with minimum height
  177.     int height = 1;
  178.     do
  179.     {
  180.         //get a random float from 0 to 1
  181.         float random = static_cast<float>(rand() / static_cast<float>(RAND_MAX));
  182.         //if probability fits in the number, increase the height and calculate again
  183.         if (probability < random)
  184.         {
  185.             ++height;
  186.         }
  187.         //if it doesn't, we return the current height
  188.         else
  189.         {
  190.             break;
  191.         }
  192.     } while (height <= maxHeight); //don't exceed the maximum height
  193.     return height;
  194. }
  195.  
  196. /*
  197. template <class Key, class Obj>
  198. SkipList<Key, Obj>::iterator SkipList<Key, Obj>::begin()
  199. {
  200.     return iterator(head);
  201. }
  202.  
  203. template <class Key, class Obj>
  204. SkipList<Key, Obj>::iterator SkipList<Key, Obj>::end()
  205. {
  206.     return iterator(tail);
  207. }
  208.  
  209. template <class Key, class Obj>
  210. SkipList<Key, Obj>::iterator::iterator(SkipNode<Key, Obj>* ptr)
  211. {
  212.     cur = ptr;
  213. }
  214.  
  215. template <class Key, class Obj>
  216. iterator SkipList<Key, Obj>::iterator::operator++()
  217. {
  218.     cur = cur->forwardNodes[1];
  219. }
  220. */
Add Comment
Please, Sign In to add comment