Linked List Operations and Array-Based Implementations

Header File Inclusion

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

Data Type Defniition

Using a type alias improves maintainability and simplifies type changes across the codebase:

typedef int ElementDataType;

Node Structure Definition

typedef struct ListNode {
    ElementDataType value;
    struct ListNode* next;
} LinkedListNode;

Core Linked List Functions

1. Printing the List

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

2. Node Creation

LinkedListNode* CreateNode(ElementDataType value) {
    LinkedListNode* newNode = (LinkedListNode*)malloc(sizeof(LinkedListNode));
    if (!newNode) {
        perror("Memory allocation failed!");
        exit(EXIT_FAILURE);
    }
    newNode->value = value;
    newNode->next = NULL;
    return newNode;
}

3. Append Node at End

void AppendNode(LinkedListNode** headRef, ElementDataType value) {
    assert(headRef);
    LinkedListNode* newNode = CreateNode(value);
    
    if (!*headRef) {
        *headRef = newNode;
        return;
    }
    
    LinkedListNode* tail = *headRef;
    while (tail->next) {
        tail = tail->next;
    }
    tail->next = newNode;
}

4. Insert at Begnining

void InsertAtStart(LinkedListNode** headRef, ElementDataType value) {
    assert(headRef);
    LinkedListNode* newNode = CreateNode(value);
    newNode->next = *headRef;
    *headRef = newNode;
}

5. Remove Last Node

void RemoveLastNode(LinkedListNode** headRef) {
    assert(headRef && *headRef);
    
    if (!(*headRef)->next) {
        free(*headRef);
        *headRef = NULL;
        return;
    }
    
    LinkedListNode* current = *headRef;
    LinkedListNode* prev = NULL;
    
    while (current->next) {
        prev = current;
        current = current->next;
    }
    
    prev->next = NULL;
    free(current);
}

6. Remove First Node

void RemoveFirstNode(LinkedListNode** headRef) {
    assert(headRef && *headRef);
    LinkedListNode* secondNode = (*headRef)->next;
    free(*headRef);
    *headRef = secondNode;
}

7. Search for Value

LinkedListNode* FindValue(LinkedListNode** headRef, ElementDataType target) {
    assert(headRef);
    LinkedListNode* current = *headRef;
    while (current) {
        if (current->value == target) {
            return current;
        }
        current = current->next;
    }
    return NULL;
}

8. Insert Before Position

void InsertBefore(LinkedListNode** headRef, LinkedListNode* position, ElementDataType value) {
    assert(headRef && position && *headRef);
    
    if (*headRef == position) {
        InsertAtStart(headRef, value);
        return;
    }
    
    LinkedListNode* current = *headRef;
    while (current && current->next != position) {
        current = current->next;
    }
    
    if (!current) return;
    
    LinkedListNode* newNode = CreateNode(value);
    current->next = newNode;
    newNode->next = position;
}

9. Insert After Posiiton

void InsertAfter(LinkedListNode* position, ElementDataType value) {
    assert(position);
    LinkedListNode* newNode = CreateNode(value);
    newNode->next = position->next;
    position->next = newNode;
}

10. Delete Specific Node

void DeleteNode(LinkedListNode** headRef, LinkedListNode* position) {
    assert(headRef && *headRef && position);
    
    if (*headRef == position) {
        RemoveFirstNode(headRef);
        return;
    }
    
    LinkedListNode* current = *headRef;
    while (current && current->next != position) {
        current = current->next;
    }
    
    if (!current) return;
    
    current->next = position->next;
    free(position);
}

11. Delete Next Node

void DeleteNextNode(LinkedListNode* position) {
    assert(position && position->next);
    LinkedListNode* toDelete = position->next;
    position->next = toDelete->next;
    free(toDelete);
}

12. Destroy Entire List

void DestroyList(LinkedListNode** headRef) {
    assert(headRef && *headRef);
    LinkedListNode* current = *headRef;
    while (current) {
        LinkedListNode* next = current->next;
        free(current);
        current = next;
    }
    *headRef = NULL;
}

Array-Based Linked List Implementations

1. Single-Linked List with Array

#include <stdio.h>
const int MAX_NODES = 100010;

int head;
int valueStore[MAX_NODES];
int nextPointer[MAX_NODES];
int currentIndex;

void InitializeList() {
    head = -1;
    currentIndex = 0;
}

void InsertAtHead(int value) {
    valueStore[currentIndex] = value;
    nextPointer[currentIndex] = head;
    head = currentIndex++;
}

void InsertAfterIndex(int index, int value) {
    valueStore[currentIndex] = value;
    nextPointer[currentIndex] = nextPointer[index];
    nextPointer[index] = currentIndex++;
}

void RemoveAfterIndex(int index) {
    nextPointer[index] = nextPointer[nextPointer[index]];
}

2. Double-Linked List with Array

const int MAX_DOUBLE_NODES = 100010;
int element[MAX_DOUBLE_NODES];
int leftPointer[MAX_DOUBLE_NODES];
int rightPointer[MAX_DOUBLE_NODES];
int doubleIndex;

void InitializeDoubleList() {
    rightPointer[0] = 1;
    leftPointer[1] = 0;
    doubleIndex = 2;
}

void InsertRight(int index, int value) {
    element[doubleIndex] = value;
    rightPointer[doubleIndex] = rightPointer[index];
    leftPointer[doubleIndex] = index;
    leftPointer[rightPointer[index]] = doubleIndex;
    rightPointer[index] = doubleIndex++;
}

void InsertLeft(int index, int value) {
    element[doubleIndex] = value;
    rightPointer[doubleIndex] = index;
    leftPointer[doubleIndex] = leftPointer[index];
    rightPointer[leftPointer[index]] = doubleIndex;
    leftPointer[index] = doubleIndex++;
}

void RemoveNode(int index) {
    rightPointer[leftPointer[index]] = rightPointer[index];
    leftPointer[rightPointer[index]] = leftPointer[index];
}

Tags: data-structures linked-list array-implementation c-memory-management

Posted on Tue, 21 Jul 2026 16:18:22 +0000 by iskawt