C Program To Create A Linked List

5 min read

A linked list is a fundamental linear data structure where elements, called nodes, are not stored in contiguous memory locations. On top of that, instead, each node contains a data field and a pointer (or reference) to the next node in the sequence. This dynamic memory allocation allows for efficient insertions and deletions without the overhead of shifting elements, a common bottleneck in static arrays. Mastering the implementation of a linked list in C is a rite of passage for every programmer, as it solidifies understanding of pointers, memory management, and structural logic—skills that transfer directly to systems programming, embedded development, and algorithm design.

Understanding the Core Concepts

Before diving into the code, Visualize the anatomy of a linked list — this one isn't optional. Unlike an array where the index dictates the position, a linked list relies entirely on the chain of pointers.

The Node Structure

The building block is the node. In C, we define this using a struct. A standard singly linked list node requires two members:

  1. Data: An integer, float, character, or even another structure holding the actual value.
  2. Next Pointer: A pointer of the same structure type that holds the memory address of the subsequent node.
struct Node {
    int data;
    struct Node* next;
};

The struct Node* next declaration is the recursive element that makes the chain possible. The last node in the list points to NULL, signifying the end of the sequence.

Head Pointer

The entry point to the entire list is the head pointer. It stores the address of the very first node. If the head is NULL, the list is empty. Losing the head pointer effectively loses the entire list, as there is no backward traversal in a singly linked list Most people skip this — try not to. No workaround needed..

Setting Up the Development Environment

To compile and run the programs discussed here, you need a standard C compiler like GCC (GNU Compiler Collection) or Clang. Which means on Linux or macOS, GCC is usually pre-installed or available via package managers (apt install build-essential or xcode-select --install). On Windows, you can use MinGW-w64 or the Windows Subsystem for Linux (WSL).

Save your code with a .c extension (e.g., linked_list.Still, c) and compile it using the terminal:

gcc linked_list. c -o linked_list
.

## Building the Linked List: Step-by-Step Implementation

We will construct a complete, menu-driven program that supports creation, insertion (at beginning, end, and specific position), deletion, searching, and display. This modular approach uses functions for each operation, promoting clean, maintainable code.

### 1. Header Files and Global Declaration
Start by including necessary libraries and defining the node structure globally so all functions can access the type definition.

```c
#include 
#include 

// Define the Node structure
struct Node {
    int data;
    struct Node* next;
};

// Global head pointer initialized to NULL
struct Node* head = NULL;

2. Creating a New Node (Helper Function)

Repeatedly writing malloc and assignment logic is error-prone. A dedicated function to create and initialize a node reduces redundancy.

struct Node* createNode(int value) {
    // Allocate memory dynamically
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    
    // Check for memory allocation failure
    if (newNode == NULL) {
        printf("Memory allocation failed!\n");
        exit(1);
    }
    
    newNode->data = value;
    newNode->next = NULL;
    return newNode;
}

Key Insight: Always check the return value of malloc. In embedded systems or memory-constrained environments, allocation failure is a realistic scenario that must be handled gracefully.

3. Insertion Operations

Insertion logic varies based on where the new node goes.

Insert at Beginning

This is the fastest insertion—O(1) time complexity. The new node’s next points to the current head, and head updates to the new node.

void insertAtBeginning(int value) {
    struct Node* newNode = createNode(value);
    newNode->next = head;
    head = newNode;
    printf("Inserted %d at the beginning.\n", value);
}

Insert at End

This requires traversing the entire list to find the last node (where next == NULL), making it O(N).

void insertAtEnd(int value) {
    struct Node* newNode = createNode(value);
    
    // If list is empty, new node becomes head
    if (head == NULL) {
        head = newNode;
        printf("Inserted %d as the first node.\n", value);
        return;
    }
    
    // Traverse to the last node
    struct Node* temp = head;
    while (temp->next != NULL) {
        temp = temp->next;
    }
    
    temp->next = newNode;
    printf("Inserted %d at the end.\n", value);
}

Insert at Specific Position (1-based Index)

This combines traversal with pointer manipulation. We stop before the target position to link the new node Surprisingly effective..

void insertAtPosition(int value, int position) {
    if (position <= 0) {
        printf("Invalid position! Position must be >= 1.\n");
        return;
    }
    
    if (position == 1) {
        insertAtBeginning(value);
        return;
    }
    
    struct Node* newNode = createNode(value);
    struct Node* temp = head;
    
    // Traverse to node at (position - 1)
    for (int i = 1; i < position - 1 && temp != NULL; i++) {
        temp = temp->next;
    }
    
    if (temp == NULL) {
        printf("Position %d exceeds list length. Inserting at end instead.\n", position);
        insertAtEnd(value);
        // Free the node created above since insertAtEnd creates its own
        free(newNode); 
        return;
    }
    
    newNode->next = temp->next;
    temp->next = newNode;
    printf("Inserted %d at position %d.\n", value, position);
}

4. Deletion Operations

Deletion requires careful pointer rewiring and explicit memory deallocation using free() to prevent memory leaks Nothing fancy..

Delete from Beginning

Update head to the second node and free the old head.

void deleteFromBeginning() {
    if (head == NULL) {
        printf("List is empty. Nothing to delete.\n");
        return;
    }
    
    struct Node* temp = head;
    head = head->next;
    printf("Deleted %d from beginning.\n", temp->data);
    free(temp);
}

Delete from End

Requires tracking the previous node (second-to-last) to set its next to NULL.

void deleteFromEnd() {
    if (head == NULL) {
        printf("List is empty.\n");
        return;
    }
    
    // Only one node
    if (head->next == NULL) {
        printf("Deleted %d (only node).\n", head->data);
        free(head);
        head = NULL;
        return;
    }
    
    struct Node* temp = head;
    while (temp->next->next != NULL) {
        temp = temp->next;
    }
    
    printf("Deleted %d from end.\n", temp->next->data);
    free(temp->next);
    temp->next = NULL;
}

Delete by Value (Key)

This searches for a specific data value and removes the first occurrence.

void deleteByValue(int key) {
    if (head == NULL
Just Went Up

What's New Today

Try These Next

Follow the Thread

Thank you for reading about C Program To Create A Linked List. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home