Sunday 16 June 2013

Implementation of SkipList Datastructure.

#include <iostream>
#include <climits>
using namespace std;

class skipNode
{
private:
        int data;
        int height;
        skipNode **forward;
public:
        skipNode(int d,int h)
        {
            data = d;
            height = h;
            forward = new skipNode*[height];
        }
        
        // Return max height of skipList Node.
        int getHeight()
        {
            return height;
        }
        
        // Set data value of skipList Node.
        void setData(int number)
        {
             data =  number;
        }
        
        // Return Data value of skipList Node.
        int getData()
        {
            return data;
        }
        
        // Set forward[pos] = ptr
        void setForwardLink(skipNode *ptr, int pos)
        {
             forward[pos] = ptr;
        }
        
        // Return forward[index]
        skipNode* getForwardLink(int index)
        {
             return forward[index];
        }
};

class skipList
{
private:
        int maxHeight;
        skipNode *head;
        skipNode *tail;
        
        // static int count to be used as seed to srand
        static int count;
public:
        skipList()
        {
             maxHeight = 5;
             head = new skipNode(INT_MIN,maxHeight);
             tail = new skipNode(INT_MAX,maxHeight);
             for(int i=0; i<maxHeight; i++)
             {
                 head->setForwardLink(tail,i);
                 tail->setForwardLink(NULL,i);
             }
        }
        
        // Generate a random number betweem 1 - maxHeight.
        int getHeight()
        {
            count++;
            srand(count);
            return ((rand() % maxHeight) +1);
        }
        
        // Traverse and print all nodes at a level.
        void levelTraversal()
        {
             for(int level = maxHeight-1; level >=0 ; level--)
             {
                  cout<<"nLevel = "<<level;
                  skipNode *next = head->getForwardLink(level);
                  while(next != tail )
                  {
                      cout<<"t"<<next->getData();
                      next = next->getForwardLink(level);
                  }
             }
        }
        
        void insertNode(int val)
        {
             // Check if already Present.
             if(searchNode(val))
             {
                 return;
             }
             
             // If not get Random height for New Node.
             int h = getHeight();
             skipNode *newNode = new skipNode(val,h);
             
             // Need to update nodes forward pointer to point to new node.
             skipNode *curNode = head;
             for(int i=h-1; i>=0; i--)
             {
                  while(curNode->getForwardLink(i) != tail && curNode->getForwardLink(i)->getData() < val)
                  {
                      curNode = curNode->getForwardLink(i);
                  }
                  // curNode represents node at level i whose forward[i] = new Node . 
                  // copy newNode.forward[i] = curNode.forward[i]
                  newNode->setForwardLink(curNode->getForwardLink(i),i);
                  curNode->setForwardLink(newNode,i);
             }
        }
        
        // Search value if present return node else return NULL.
        skipNode* searchNode(int val)
        {
             // Start from head Node and search at topMost level.
             skipNode *ptr = head;
             for(int level = maxHeight-1; level >=0; level--)
             {
                 skipNode *nextNode = ptr->getForwardLink(level);
                 // Narrow down search from ptr to tail or node having value >= val
                 while(nextNode->getData() < val && nextNode != tail)
                 {
                      ptr = nextNode;
                      nextNode = nextNode->getForwardLink(level);
                 }
                 if(nextNode->getData() == val)
                      return nextNode;
             }
             return NULL;
        }
        
        void deleteNode(int val)
        {
             // check if node exist
             skipNode *toDelete = searchNode(val);
             if(toDelete)
             {
                 // Get height of node to be deleted.
                 int level = toDelete->getHeight();
                 
                 // forward pointer of nodes just before delete node neeeds updation of forward pointer.
                 skipNode *curNode = head;
                 for(int i=level-1; i>=0; i--)
                 {
                      while(curNode->getForwardLink(i) != toDelete)
                      {
                          curNode = curNode->getForwardLink(i);
                      } 
                      curNode->setForwardLink(toDelete->getForwardLink(i),i);
                 }
             }
             else
             {
                 return;
             }
        }
        
        void displaySkipList()
        {             
             for(int level = maxHeight-1; level >=0; level--)
             {
                 cout<<"n";
                 skipNode* ptr = head;
                 while(ptr != tail)
                 {
                      cout<<" "<<ptr->getData();
                      ptr = ptr->getForwardLink(level);
                 }
             }
        }
};

int skipList::count = 0;
int main()
{
    skipList list ;
    list.insertNode(10);
    list.insertNode(20);
    list.insertNode(40);
    list.insertNode(50);
    list.insertNode(60);
    list.insertNode(70);
    list.insertNode(30);
    list.levelTraversal();
    list.deleteNode(40);
    cout<<"nnAFTER DELETION";
    list.levelTraversal();
    system("pause");
}

No comments:

Post a Comment