Saturday, 14 November 2015

Object Oriented implementation of Singly Linked List in C

Hi folks, 

How are you doing, Have you got a chance to see my last blog. Please have a look and do comment.
Yet again i have implemented one more data structure in c++ style. This time it is singly linked list. There are three files LinkedList.h, LinkedList.c and main.c. I tested it on my system many times and seems to have no issue, Nevertheless your valuable inputs are welcome, please do comment. I will modify the code accordingly. Feel free to use the code for educational purpose. 


/*Rev 0: First implementation*/
///////////////////////////////////////////////////////////////////////
/***********************LinkedList.h******************/
///////////////////////////////////////////////////////////////////////

#ifndef LINKEDLIST_H
#define LINKEDLIST_H

typedef struct LinkedListClass
{
    void *Head;
    unsigned int DataCount;
    unsigned int DataSize;
    void* (*CreateNewNode)();
    char (*AddNode)(void *Object, void* Data);
    char (*RemoveNode)(void*Object);
    char (*InsertNode)(void*Object, void* Data, unsigned int Position);
    char (*DeleteNode)(void*Object, unsigned int Position);
    void* (*ReadNode)(void*Object, unsigned int Position);
    char (*ModifyNode)(void*Object, void* Data, unsigned int Position);
    char (*DeleteLinkedList)(struct LinkedListClass** Object);
    unsigned int (*LinkedListSize)(void*);
   
}LINKED_LIST_CLASS;


extern LINKED_LIST_CLASS * ConstructLinkedList(unsigned int);
extern char DeleteLinkedList(LINKED_LIST_CLASS** );

/**********Function reply definitions**********/ 
#define SUCCESS 0
#define WRONG_POSITION -1
#define NO_MEMORY_NEW_NODE -2
#define NO_MEMORY_DATA -3
#define LIST_EMPTY -4
#define LINKED_LIST_DOES_NOT_EXIST -5

#endif  /* LINKEDLIST_H */

 ///////////////////////////////////////////////////////////////////////
/********************LinkedList.c*********************/
///////////////////////////////////////////////////////////////////////

#include "stdlib.h"
#include "string.h" 
#include "LinkedList.h"
/**************************************************************/
typedef struct Node
{
    void* Data;
    struct Node *Next;
}NODE;
/**************************************************************/
static void* CreateNewNode()
{
    NODE* NewNode = (NODE*)malloc(sizeof(NODE));
    if(NewNode == NULL)
        return NULL;
    NewNode->Next = NULL;
    return NewNode;
}
/**************************************************************/
static unsigned int LinkedListSize(void *Object)
{
    if (Object == NULL)
        return LINKED_LIST_DOES_NOT_EXIST;
    LINKED_LIST_CLASS *Self = (LINKED_LIST_CLASS*)Object;
    return Self->DataCount;
}
/**************************************************************/
static char ModifyNode(void *Object, void* Data, unsigned int Position)
{
    if (Object == NULL)
        return LINKED_LIST_DOES_NOT_EXIST;
    LINKED_LIST_CLASS *Self = (LINKED_LIST_CLASS*)Object;
    if(Position >= Self->DataCount)
    {
        return WRONG_POSITION;
    }
    NODE* temp = (NODE*)Self->Head;
    unsigned int i;
    for(i=0; i<Position; i++)
    {
        temp = temp->Next;
    }
    memcpy(temp->Data, Data, Self->DataSize);
    return SUCCESS;
}
/**************************************************************/
static void* ReadNode(void *Object, unsigned int Position)
{
    if (Object == NULL)
        return NULL;
    LINKED_LIST_CLASS *Self = (LINKED_LIST_CLASS*)Object;
    if(Position >= Self->DataCount)
    {
        return NULL;
    }
    NODE*temp = (NODE*)Self->Head;
    unsigned int i;
    for(i=0; i<Position; i++)
    {
        temp = temp->Next;
    }
    return temp->Data;
}
/**************************************************************/
static char DeleteNode(void* Object, unsigned int Position)
{
    if (Object == NULL)
        return LINKED_LIST_DOES_NOT_EXIST;
    LINKED_LIST_CLASS *Self = (LINKED_LIST_CLASS*)Object;
    NODE* temp = (NODE*)Self->Head;
    if(Position >= Self->DataCount)
    {
        return WRONG_POSITION;
    }
    if(Position == 0)
    {
         Self->Head = temp->Next;
         free(temp->Data);
         free(temp);
    }
    else
    {
        unsigned int i;
        for(i=0; i<Position-1; i++)
        {
            temp = temp->Next;
        }
        NODE *temp1 = temp->Next;
        temp->Next = temp1->Next;
        free(temp1->Data);
        free(temp1);
    }
    Self->DataCount--;
   
    return SUCCESS; 
}
/**************************************************************/
static char InsertNode(void *Object, void* Data, unsigned int Position)
{
    if (Object == NULL)
        return LINKED_LIST_DOES_NOT_EXIST;
    LINKED_LIST_CLASS *Self = (LINKED_LIST_CLASS*)Object;
    if(Position > Self->DataCount)
    {
        return WRONG_POSITION;
    }
    NODE* NewNode = (NODE*)Self->CreateNewNode();
    if(NewNode == NULL)
    {
        return NO_MEMORY_NEW_NODE;       
    }
    NewNode->Data =  malloc(Self->DataSize);
    if(NewNode->Data == NULL)
    {
        free(NewNode);
        return NO_MEMORY_DATA;
    }
    memcpy(NewNode->Data, Data, Self->DataSize);
    if(Position == 0)
    {
        NewNode->Next = (NODE*)Self->Head;
        Self->Head = NewNode;
    }
    else
    {
        NODE* TempNode = (NODE*)Self->Head;
        unsigned int i;
        for(i=0; i<Position-1; i++)
        {
            TempNode = TempNode->Next;
        }
        NewNode->Next = TempNode->Next;
        TempNode->Next = NewNode;
       
    }
    Self->DataCount++;
    return SUCCESS;
}
/**************************************************************/
static char AddNode(void *Object, void* Data)
{
    if (Object == NULL)
        return LINKED_LIST_DOES_NOT_EXIST;
    LINKED_LIST_CLASS *Self = (LINKED_LIST_CLASS*)Object;
    NODE* NewNode = (NODE*)Self->CreateNewNode();
    if(NewNode == NULL)
    {
        return NO_MEMORY_NEW_NODE;       
    }
    NewNode->Data =  malloc(Self->DataSize);
    if(NewNode->Data == NULL)
    {
        free(NewNode);
        return NO_MEMORY_DATA;
    }
    memcpy(NewNode->Data, Data, Self->DataSize);
     
    if(Self->Head == NULL)
        Self->Head = NewNode;
    else
    {
        NODE* TempNode = (NODE*)Self->Head;
        while(TempNode->Next!= NULL)
            TempNode = TempNode->Next;
        TempNode->Next = NewNode;
    }
    Self->DataCount++;
    return SUCCESS;
}
/**************************************************************/
static char RemoveNode(void* Object)
{
    if (Object == NULL)
        return LINKED_LIST_DOES_NOT_EXIST;
    LINKED_LIST_CLASS *Self = (LINKED_LIST_CLASS*)Object;
    NODE* TempNode = (NODE*)Self->Head;
    if(Self->DataCount == 0)
        return LIST_EMPTY;
    else if(Self->DataCount == 1)
    {
        Self->Head = NULL;
        free(TempNode->Data);
        free(TempNode);
    }
    else
    {
        unsigned int i;
        for(i=0; i<Self->DataCount-2; i++)
        {
            TempNode = TempNode->Next;
        }
        free(TempNode->Next->Data);
        free(TempNode->Next);
    }
    Self->DataCount--;
   
    return SUCCESS; 
}
/**************************************************************/
char DeleteLinkedList(LINKED_LIST_CLASS** Self)
{
    NODE* TempNode ;
    if (*Self == NULL)
        return SUCCESS;   
    while((*Self)->Head != NULL)
    {
        TempNode = (NODE*)(*Self)->Head;
        (*Self)->Head = TempNode->Next;
        free(TempNode->Data);
        free(TempNode);
        (*Self)->DataCount--;
    }
    free(*Self);
    *Self = NULL;
    return SUCCESS;
}
/**************************************************************/
LINKED_LIST_CLASS * ConstructLinkedList(unsigned int DataSize)
{
    LINKED_LIST_CLASS *LL= (LINKED_LIST_CLASS*)(malloc(sizeof(LINKED_LIST_CLASS)));
    if(LL == NULL)
        return NULL;
    LL->DataSize = DataSize;
    LL->CreateNewNode = CreateNewNode;
    LL->DataCount = 0;
    LL->AddNode = AddNode;
    LL->RemoveNode = RemoveNode;
    LL->DeleteNode = DeleteNode;
    LL->Head = (NODE*)NULL;
    LL->InsertNode = InsertNode;
    LL->ReadNode = ReadNode;
    LL->ModifyNode = ModifyNode;
    LL->LinkedListSize = LinkedListSize;
    LL->DeleteLinkedList = DeleteLinkedList;
    return LL;
      
}



  
 //////////////////////////////////////////////////////////////////////
/**********************main.c*********************/
//////////////////////////////////////////////////////////////////////

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

#include "LinkedList.h"
#include "LinkedList.c"

/***************User defined data type*************************/
typedef struct data
{
     int x;
}DATA;
/**************************************************************/

int main()
{
    LINKED_LIST_CLASS * LL1 = ConstructLinkedList(sizeof(DATA));
    DATA data;
    int cases;
   
    while(1)
    {
        printf("Enter following options\n");
        printf("1: Add Node\n");
        printf("2: Remove Node\n");
        printf("3: Insert Node\n");
        printf("4: Delete Node\n");
        printf("5: Modify Node\n");
        printf("6: Read Node\n");
        printf("7: Read Size\n");
        printf("8: Quit\n");
        scanf("%c",&cases);
        switch(cases)
        {
            case 1:
            {
                printf("Enter data\t");
                scanf("%d",&data.x);
                printf("%d\n\n",(int)(LL1->AddNode(LL1,&data)));
                break;
            }
       
            case 2:
            {
                printf("%d\n\n",(int)(LL1->RemoveNode(LL1)));
                break;
            }
           
            case 3:
            {
                int position;
                printf("Enter data\t");
                scanf("%d",&data.x);
                printf("Enter Position\t");
                scanf("%d",&position);
                printf("%d\n\n",(int)(LL1->InsertNode(LL1,&data,position)));
                break;
            }
           
            case 4:
            {
                int position;
                printf("Enter Position\t");
                scanf("%d",&position);
                printf("%d\n\n",(int)(LL1->DeleteNode(LL1,position)));
                break;
            }
            case 5:
            {
                int position;
                printf("Enter data\t");
                scanf("%d",&data.x);
                printf("Enter Position\t");
                scanf("%d",&position);
                printf("%d\n\n",(int)(LL1->ModifyNode(LL1,&data,position)));
                break;
            }
            case 6:
            {
                DATA *TempData;
                int position;
                printf("Enter Position\t");
                scanf("%d",&position);
                TempData = LL1->ReadNode(LL1, position);
                if(TempData == NULL)
                    printf ("Wrong Position\t");
                else
                    printf("%d\n\n",(int)TempData->x);
                break;
            }
           
            case 7:
            {
                printf("%d\n\n",(int)(LL1->LinkedListSize(LL1)));
                break;
            }
               
            case 8:
            {
                DeleteLinkedList(&LL1);
                exit(0);
                break;
            }
           
           
        }
   
    }
    return 0;
}