Fading Coder

One Final Commit for the Last Sprint

Home > Notes > Content

Implementing a Singly Linked List from Scratch

Notes Aug 1 2

Introducsion to Singly Linked Lists

A singly linked list can be visualized as a train where each car carries cargo and a link to the next car. Similar, each node in a singly linked list contains data and a pointer to the next node.

The structure of a singly linked list node is defined as:

typedef int SLTDataType;

typedef struct SListNode
{
    int data;
    struct SListNode* next;
}SListNode;

Key characteristics of singly linked lists:

  • Physically non-linear storage
  • Logically linear arrangement

Core Implementation

Display Function

This function traverses and displays all elements in the list:

void SListPrint(SListNode* head)
{
    SListNode* current = head;
    while (current)
    {
        printf("%d->", current->data);
        current = current->next;
    }
    printf("NULL\n");
}

Node Creation

Helper function to allocate and initialize new nodes:

SListNode* CreateNode(SLTDataType value)
{
    SListNode* node = (SListNode*)malloc(sizeof(SListNode));
    if (node == NULL)
    {
        perror("Memory allocation failed");
        exit(1);
    }
    node->data = value;
    node->next = NULL;
    return node;
}

Insertion Operations

Tail Insertion

void SListAppend(SListNode** headRef, SLTDataType value)
{
    assert(headRef);

    SListNode* newNode = CreateNode(value);

    if (*headRef == NULL)
    {
        *headRef = newNode;
    }
    else
    {
        SListNode* current = *headRef;
        while (current->next)
        {
            current = current->next;
        }
        current->next = newNode;
    }
}

Head Insertion

void SListPrepend(SListNode** headRef, SLTDataType value)
{
    assert(headRef);

    SListNode* newNode = CreateNode(value);
    newNode->next = *headRef;
    *headRef = newNode;
}

Deletion Operations

Tail Deletion

void SListRemoveTail(SListNode** headRef)
{
    assert(headRef && *headRef);

    if ((*headRef)->next == NULL)
    {
        free(*headRef);
        *headRef = NULL;
    }
    else
    {
        SListNode* current = *headRef;
        SListNode* previous = *headRef;

        while (current->next)
        {
            previous = current;
            current = current->next;
        }
        free(current);
        previous->next = NULL;
    }
}

Head Deletion

void SListRemoveHead(SListNode** headRef)
{
    assert(headRef && *headRef);

    SListNode* nextNode = (*headRef)->next;
    free(*headRef);
    *headRef = nextNode;
}

Search Functionality

SListNode* SListSearch(SListNode* head, SLTDataType target)
{
    SListNode* current = head;
    while (current)
    {
        if (current->data == target)
        {
            return current;
        }
        current = current->next;
    }
    return NULL;
}

Position-Based Operations

Delete Specific Node

void SListRemoveNode(SListNode** headRef, SListNode* target)
{
    assert(headRef && *headRef);
    assert(target);

    if (target == *headRef)
    {
        SListRemoveHead(headRef);
    }
    else
    {
        SListNode* current = *headRef;
        while (current->next != target)
        {
            current = current->next;
        }
        current->next = target->next;
        free(target);
    }
}

Delete Node After Position

void SListRemoveAfter(SListNode* position)
{
    assert(position && position->next);
    SListNode* nodeToRemove = position->next;
    position->next = nodeToRemove->next;
    free(nodeToRemove);
}

Insert Before Position

void SListInsertBefore(SListNode** headRef, SListNode* position, SLTDataType value)
{
    assert(headRef && *headRef);
    assert(position);

    if (*headRef == position)
    {
        SListPrepend(headRef, value);
    }
    else
    {
        SListNode* newNode = CreateNode(value);
        SListNode* current = *headRef;
        while (current->next != position)
        {
            current = current->next;
        }
        newNode->next = position;
        current->next = newNode;
    }
}

Insert After Position

void SListInsertAfter(SListNode* position, SLTDataType value)
{
    assert(position);

    SListNode* newNode = CreateNode(value);
    SListNode* nextNode = position->next;
    position->next = newNode;
    newNode->next = nextNode;
}

List Destruction

void SListDestroy(SListNode** headRef)
{
    SListNode* current = *headRef;
    while (current)
    {
        SListNode* next = current->next;
        free(current);
        current = next;
    }
    *headRef = NULL;
}

Interface Header

#pragma once

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

typedef int SLTDataType;

typedef struct SListNode
{
    int data;
    struct SListNode* next;
}SListNode;

void SListPrint(SListNode* head);
void SListAppend(SListNode** headRef, SLTDataType value);
void SListPrepend(SListNode** headRef, SLTDataType value);
void SListRemoveTail(SListNode** headRef);
void SListRemoveHead(SListNode** headRef);
SListNode* SListSearch(SListNode* head, SLTDataType target);
void SListRemoveNode(SListNode** headRef, SListNode* target);
void SListRemoveAfter(SListNode* position);
void SListInsertBefore(SListNode** headRef, SListNode* position, SLTDataType value);
void SListInsertAfter(SListNode* position, SLTDataType value);
void SListDestroy(SListNode** headRef);

Related Articles

Designing Alertmanager Templates for Prometheus Notifications

How to craft Alertmanager templates to format alert messages, improving clarity and presentation. Alertmanager uses Go’s text/template engine with additional helper functions. Alerting rules referenc...

Deploying a Maven Web Application to Tomcat 9 Using the Tomcat Manager

Tomcat 9 does not provide a dedicated Maven plugin. The Tomcat Manager interface, however, is backward-compatible, so the Tomcat 7 Maven Plugin can be used to deploy to Tomcat 9. This guide shows two...

Skipping Errors in MySQL Asynchronous Replication

When a replica halts because the SQL thread encounters an error, you can resume replication by skipping the problematic event(s). Two common approaches are available. Methods to Skip Errors 1) Skip a...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.