Implement Linked List in C

Implement Linked List in C. Self-referential structures

Before starting to implement linked list in C, let’s see what self-referential structures are. Also, you need to know about dynamic memory allocation, which you can find here in this link. For example, let’s define a structure like below:

struct node {
    int data;
    struct node *nextPtr;
}; // end struct node

In the above struct node, we have two members, viz. integer member data and pointer member nextPtr. Also, the pointer points to same type struct node, hence the name self-referential structure. Moreover, it is also called a link.

Linked List in C

A linked list is a linear collection of self-referential structures, called nodes, connected by pointer links. That is why, the term ‘linked’ list. We can access a linked list via a pointer to the first node of the list. On the other hand, we access the subsequent nodes via the link pointer member which we store in each node. Finally, by convention, we set the link pointer in the last node to NULL to mark the end of the list. Also, we store the data dynamically in a linked list. Furthermore, a node can contain data of any type including other structs.

Implementation Example

Now, we are going to implement linked list in C, which stores a character in an alphabetical order.

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

// Self-referential Structure
struct listNode {
    char data;  // A character data in the list
    struct listNode *nextPtr;   // Pointer to next node
}; // end struct listNode

typedef struct listNode ListNode; // alias for the struct
typedef ListNode *ListNodePtr;  // alias for ListNode*

// Declarations
void insert(ListNodePtr *sPtr, char value);
char delete(ListNodePtr *sPtr, char value);
int isEmpty(ListNodePtr sptr);  // Memory!
void showList(ListNodePtr currentPtr); 
void showMenu(void);

int main() {
    // Initially, there are no nodes
    ListNodePtr startPtr = NULL;
    // User's choice
    unsigned int ch;
    // User's entered character
    char item;
    
    // Display the menu
    showMenu();
    printf("? ");
    scanf("%u", &ch);
    
    // Loop unless user chooses 3
    while(ch != 3) {
        switch(ch) {
            case 1:
                printf("Enter a character: ");
                scanf("\n%c", &item);
                
                // insert the item in list
                insert(&startPtr, item);
                showList(startPtr);
                break;
            case 2:
                // if list is not empty
                if(!isEmpty(startPtr)) {
                    printf("Enter character to be deleted: ");
                    scanf("\n%c", &item);
                    
                    // Remove the character if found
                    if (delete(&startPtr, item)) {
                        printf("%c deleted.\n", item);
                        showList(startPtr);
                    }
                    else {
                        printf("%c not found. \n\n", item);
                    }
                }
                else {
                    printf("The list is empty. \n");
                }
                
                break;
            default:
                printf("Invalid choice.\n");
                showMenu();
                break;
        }
        showMenu();
        printf("? ");
        scanf("%u", &ch);
    }
    printf("Thank You!\n");
    return 0;
}

// Display Menu Function
void showMenu(void) {
    printf("Enter your choice:\n"
        "   1 to insert element into the list.\n"
        "   2 to delete element from the list.\n"
        "   3 to end" );
}

// insert a new value into the list in sorted order
void insert(ListNodePtr *sPtr, char value) {
    ListNodePtr newPtr; // pointer to new node
    ListNodePtr previousPtr;    // pointer to previous node
    ListNodePtr currentPtr;     // pointer to current node
    
    newPtr = malloc(sizeof(ListNode)); // Create a node
    
    // if allocated
    if (newPtr != NULL) {
        newPtr->data = value;   // put value in the node
        newPtr->nextPtr = NULL; // doesn't have to link to another node
        
        previousPtr = NULL;
        currentPtr = *sPtr;
        
        // find the correct location in the list
        while(currentPtr != NULL && value > currentPtr->data) {
            previousPtr = currentPtr;
            currentPtr = currentPtr->nextPtr;
        }
        
        // insert new node at beginning of list
        if (previousPtr == NULL) {
            newPtr->nextPtr = *sPtr;
            *sPtr = newPtr;
        }
        else {
            previousPtr->nextPtr = newPtr;
            newPtr->nextPtr = currentPtr;
        }
    }
    else {
        printf("%c is not inserted. \n", value);
    }
}

// delete a list element
char delete(ListNodePtr *sPtr, char value) {
    ListNodePtr previousPtr;
    ListNodePtr currentPtr;
    ListNodePtr tmpPtr;
    
    // delete first node
    if (value == (*sPtr)->data) {
        tmpPtr = *sPtr; // hold onto node being removed
        *sPtr = (*sPtr)->nextPtr; // de-thread the node
        free(tmpPtr);   // free the de-threaded node
        return value;
    }
    else {
        previousPtr = *sPtr;
        currentPtr = (*sPtr)->nextPtr;
        
        // find the correct location in the list
        while (currentPtr != NULL && currentPtr->data != value) {
            previousPtr = currentPtr;
            currentPtr = currentPtr->nextPtr;
        }
        
        // delete node at currentPtr
        if (currentPtr != NULL) {
            tmpPtr = currentPtr;
            previousPtr->nextPtr = currentPtr->nextPtr;
            free(tmpPtr);
            return value;
        }
    }
    return '\0'; // NULL
}

// return 1 if the list is empty, otherwise 0
int isEmpty(ListNodePtr sPtr) {
    return sPtr == NULL;
}

// show the list
void showList(ListNodePtr currentPtr) {
    // if list is empty
    if (isEmpty(currentPtr)) {
        printf("The list is empty!\n");
    }
    else {
        printf("The list is: \n");
        
        // while not the end of list
        while(currentPtr != NULL) {
            printf("%c ==> ", currentPtr->data);
            currentPtr = currentPtr->nextPtr;
        }
        printf("NULL\n");
    }
}

In the above example, we saw how we can perform insert and delete operations in linked list. It is all explained in the comments in the program. In a nutshell, you have to create a new node and point to its address from previous node. On the other hand, while deleting, you have to delete the node and set the nextPtr of previous node to NULL.

You can view the the code in the gist here.

I am a Computer Engineer from Pulchowk Campus, IOE. I love programming, and music. Python, Java, Php, Javascript, Django, Laravel, Spring, express.js, etc. are my specialities.

2 Comments

Leave a Reply

%d bloggers like this: