Singly Linked List Implementation and Operations

Structure Definition

A singly linked list is a linear data structure where elements are stored in nodes that are logically connected but physically dispersed in memory. Each node contains data and a pointer to the next node in the sequence.

typedef int DataType;
typedef struct Node {
    DataType value;
    struct Node* next;
} ListNode;

In this implementation:

  • Nodes are unidirectionally connected
  • No sentinel head node is used
  • The last node points to NULL, making it non-circular

Core Operations

Node Creation

Creating a new node involves allocating memory and initializing its fields:

ListNode* createNode(DataType data) {
    ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
    if (!newNode) {
        perror("Memory allocation failed");
        exit(EXIT_FAILURE);
    }
    newNode->value = data;
    newNode->next = NULL;
    return newNode;
}

Traversal and Display

Iterating through the list to display all elements:

void displayList(ListNode* head) {
    ListNode* current = head;
    while (current) {
        printf("%d -> ", current->value);
        current = current->next;
    }
    printf("NULL\n");
}

Tail Insertion

Adding an element at the end of the list:

void appendNode(ListNode** headRef, DataType data) {
    ListNode* newNode = createNode(data);
    
    if (!*headRef) {
        *headRef = newNode;
        return;
    }
    
    ListNode* current = *headRef;
    while (current->next) {
        current = current->next;
    }
    current->next = newNode;
}

Head Insertion

Inserting an element at the beginning:

void prependNode(ListNode** headRef, DataType data) {
    ListNode* newNode = createNode(data);
    newNode->next = *headRef;
    *headRef = newNode;
}

Tail Deletion

Removing the last element requires special handling for single-node lists:

void removeTail(ListNode** headRef) {
    if (!*headRef) return;
    
    if (!(*headRef)->next) {
        free(*headRef);
        *headRef = NULL;
        return;
    }
    
    ListNode* previous = *headRef;
    ListNode* current = (*headRef)->next;
    
    while (current->next) {
        previous = current;
        current = current->next;
    }
    
    free(current);
    previous->next = NULL;
}

Head Deletion

Removing the first element:

void removeHead(ListNode** headRef) {
    if (!*headRef) return;
    
    ListNode* temp = *headRef;
    *headRef = (*headRef)->next;
    free(temp);
}

Element Search

Finding a specific value in the list:

ListNode* findElement(ListNode* head, DataType target) {
    ListNode* current = head;
    while (current) {
        if (current->value == target) {
            return current;
        }
        current = current->next;
    }
    return NULL;
}

Arbitrary Position Insertion

Inserting before a specific node:

void insertBefore(ListNode** headRef, ListNode* target, DataType data) {
    if (!target || !*headRef) return;
    
    if (target == *headRef) {
        prependNode(headRef, data);
        return;
    }
    
    ListNode* current = *headRef;
    while (current->next && current->next != target) {
        current = current->next;
    }
    
    if (current->next == target) {
        ListNode* newNode = createNode(data);
        newNode->next = target;
        current->next = newNode;
    }
}

Memory Deallocation

Properly freeing all allocated memory:

void destroyList(ListNode** headRef) {
    ListNode* current = *headRef;
    ListNode* nextNode;
    
    while (current) {
        nextNode = current->next;
        free(current);
        current = nextNode;
    }
    *headRef = NULL;
}

Characteristics

Linked lists provide O(1) insertion and deletion at both ends when proper references are maintained. However, they do not support random access and require sequential traversal for element retrieval. Memory overhead per element is higher compared to arays due to pointer storage, but dynamic sizing eliminates pre-allocation concerns.

Tags: data-structures linked-list c-programming memory-management algorithms

Posted on Sun, 27 Sep 2026 16:24:01 +0000 by gurroa