Home > other >  Skip list getting lost when either inserting with a new level or adding a new node to lower level
Skip list getting lost when either inserting with a new level or adding a new node to lower level

Time:12-27

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>

#define Malloc(n, type) (type *)malloc((unsigned)((n) * sizeof(type)))
#define Realloc(ptr, n, type) (type *)realloc(ptr, (n) * sizeof(type))

typedef struct Node
{
    int key;
    struct Node *next;
    struct Node *down;
} Node;

typedef struct
{
    int level;
    struct Node *header;
} skiplist;

int level()
{
    /*
    This function takes the coin flip and decides the level of the node with each
    level having a probability of 0.25.

    arg: void
    return: a number from the set {1,2,3, 4}
    */
    int level = 1;
    for (int i = 0; i < 3; i  )
    {
        unsigned int coin = (unsigned int)rand();
        coin = coin % 2;
        if (coin)
        {
            level  ;
        }
        else
            break;
    }
    return level;
}

skiplist skip_list_init();

Node *Traverse_Express(Node *, int);

Node *skip_list_search(skiplist, int);

Node *insert_level(Node *, int, int, int);

void skip_list_insert(skiplist *, int);

void skip_print(skiplist);

int main()
{
    srand(time(0));
    int arr[10000];
    for (int i = 0; i < 10; i  )
    {
        arr[i] = (int)rand();
    }
    printf("The array is initialised\n");
    skiplist list;
    list = skip_list_init();
    printf("The Skip list is initialised\n");
    if (list.header == NULL)
    {
        printf("List is null\n");
    }
    for (int i = 0; i < 10; i  )
    {
        skip_list_insert(&list, arr[i]);
        printf("The %d element is initialised with key: %d\n", i, arr[i]);
    }
    printf("The skip list is:\n");
    skip_print(list);
    return 0;
}

void skip_print(skiplist list)
{
    /*
    The function prints the skip list level-wise.

    arg: list
    return: none
    */
    Node *temp = list.header;
    int count = 0;
    for (int i = list.level; i > 0; i--)
    {
        printf("The Keys at level %d:\n", i);
        while (NULL != temp->next)
        {
            printf("%d ->", temp->key);
            temp = temp->next;
        }
        printf("%d\n", temp->key);
        int dummy = count;
        temp = list.header;
        while (dummy)
        {
            temp = temp->down;
            dummy--;
        }
        count  ;
    }
}

skiplist skip_list_init()
{
    /*
    This function creates the first node in the skip list with key value
    to be negative infinity and level of the list =1.

    arg: None
    return: Skiplist initialised with a Node having key as INT_MIN.
    */
    skiplist list;
    Node *head;
    if (NULL == (head = Malloc(1, Node)))
    {
        exit(1);
    }
    list.header = head;
    list.level = 1;
    head->key = INT_MIN;
    head->next = NULL;
    head->down = NULL;
    return list;
}

Node *skip_list_search(skiplist list, int key)
{
    /*
    The function returns a pointer to the either the key itself if present
    or the key immediatedly smaller than the searched key.

    arg:
        list:The skiplist to be searched. Type: skiplist
        key: A key to be searched. Type: int.
    return: Type: Node pointer
        A pointer to the searched key or immediately smaller it.
    */
    if (list.header == NULL)
        exit(1);
    else
        skip_print(list);

    int level = list.level; // Number of levels already present in the list
    Node *curr = list.header;
    printf("Inside Skip search\n");
    printf("The value of level %d\n", level);
    for (; level > 0; level--)
    {
        curr = Traverse_Express(curr, key);
        if ((curr->key == key) && (INT_MIN != curr->key))
        {
            return curr;
        }
        if (NULL != curr->down)
            curr = curr->down;
    }
    printf("The value at current node %d\n", curr->key);
    printf("Leaving Skip_search\n");
    return curr;
}

Node *Traverse_Express(Node *temp, int key)
{
    printf("On the express way\n");
    printf("We are searching the key: %d\n", key);
    while (key > temp->key && NULL != temp->next)
    {
        printf("Loop of expressway\n");
        printf("The current key : %d\n", temp->key);
        if (key >= temp->next->key)
            temp = temp->next;
        else
            break;
    }
    printf("Left the express way\n");
    return temp;
}

Node *insert_level(Node *nod, int key, int lev, int list_lev)
{
    /*
    Inserting the key till the required level

    arg:
        nod: a pointer to the exsiting skip list
        key: key to be inserted
        lev: the level of the key
        list_lev: the number of levels in the given skiplist

    return: A Node pointer to the head of the skiplist with the key 
            inserted to the existing list.
    */
    Node *temp1 = nod, *temp3 = NULL;
    printf("\nStarting of insert at level procedure\n");
    // Procedure to cut-off the extra levels in the list if any
    if (lev < list_lev)
    {
        for (int i = list_lev - lev; i > 0; i--)
        {
            printf("Searching on the level: %d\n", i   lev);
            temp1 = Traverse_Express(temp1, key);
            temp1 = temp1->down;
        }
    }
    printf("The value of first node: %d\n", temp1->key);
    // Procedure to insert from the required level till level 1
    for (int i = 0; i < lev; i  )
    {
        Node *temp2 = Malloc(1, Node);
        temp2->key = key;
        temp2->next = NULL;
        temp2->down = NULL;
        temp1 = Traverse_Express(temp1, key);
        printf("Temp1 current key:%d\n", temp1->key);
        if (NULL == temp1->next)
        {
            temp1->next = temp2;
            printf("Node inserted at level: %d\n", lev - i);
        }
        else
        {
            printf("Entered the else procedure\n");
            temp2->next = temp1->next;
            temp1->next = temp2;
            printf("%d\n", temp1->next->key);
        }
        if (i > 0)
        {
            temp3->down = temp2;
        }
        temp1 = temp1->down;
        temp3 = temp2;
        /*
        free(temp2);
        if(temp3==NULL)
        {
            printf("did a fuck up\n");
            exit(1);
        }*/
    }
    skiplist list;
    // list = skip_list_init(list);
    list.header = nod;
    list.level = list_lev;
    printf("Printing skip list from insert level\n");
    skip_print(list);
    printf("End insert level procedure\n\n\n");
    temp1 = temp3 = NULL;
    return nod;
    free(temp1);
    free(temp3);
}

void skip_list_insert(skiplist *list, int key)
{
    /*
    This function finds the key value and if already present, then returns back
    else it inserts the key at its right place.

    arg: a skilplist by reference and a key
    return: None
    */
    printf("Inside skip_list_insert\n");
    Node *req = skip_list_search(*list, key);
    printf("The value returned by skip search %d\n", req->key);
    if (key == req->key)
    {
        printf("Key %d is already present in skip list\n", key);
    }
    Node *temp1 = list->header;
    int list_lev = list->level;
    printf("The list level = %d\n", list_lev);
    int lev = level();
    printf("The prob level %d\n", lev);
    Node *hold_prev = NULL;
    // creating a skip list if level returned is greater than existing one.
    if (lev > list_lev)
    {
        for (int i = lev - list_lev; i > 0; i--)
        {
            skiplist l = skip_list_init();
            Node *inser = Malloc(1, Node);
            printf("The value of i in loop %d\n", i);
            inser->key = key;
            inser->down = NULL;
            inser->next = NULL;
            l.header->next = inser;
            Node *trans = l.header;
            // Zipping the previous levels with new level
            while (NULL != hold_prev)
            {
                trans->down = hold_prev;
                trans = trans->next;
                hold_prev = hold_prev->next;
            }
            hold_prev = l.header;
            l.header = NULL;
            if (hold_prev == NULL)
            {
                printf("Big Mistake");
                exit(1);
            }
            else
            {
                printf("You are doing it correct way\n");
            }
        }
        list->header = hold_prev;
        list->level = lev - list_lev;
        skip_print(*list);
        // Returning a pointer to the zeroth element of last level in this list.
        while (NULL != hold_prev->down)
        {
            hold_prev = hold_prev->down;
        }
    }
    // Inserting the node till the min(list_lev, level())
    if (list_lev > lev)
    {
        temp1 = insert_level(temp1, key, lev, list_lev);
    }
    else
    {
        temp1 = insert_level(temp1, key, list_lev, list_lev);
    }
    skiplist l1 = skip_list_init();
    l1.header = temp1;
    l1.level = list_lev;
    skip_print(l1);

    printf("\n Now the Zipping procedure with level()>list_lev starts\n");
    // Zipping Procedure only if level()>list_lev
    if (lev > list_lev)
    {
        hold_prev->down = temp1;
        skiplist l1 = skip_list_init();
        l1.header = list->header;
        l1.level = lev;
        skip_print(l1);
        printf("the key at the first node:%d\n", temp1->key);
        hold_prev = hold_prev->next;
        while (temp1->key != key)
        {
            temp1 = temp1->next;
            printf("Zipping over keys:\n");
            printf("Current key: %d\n", temp1->key);
        }
        hold_prev->down = temp1;
        list->level = lev;
    }
    if (list_lev > lev)
    {
        list->level = list_lev;
    }
    printf("\n\n\n");
}

The above is my implementation. I have tried with all my might to debug the code but I am falling to implement a skip list for past 1 month. I genuinely request with pleading hands

  • Related