Skip to main content

Command Palette

Search for a command to run...

What is a singly linked list?

Updated
21 min read
What is a singly linked list?
C

Software Engineer

First, what is a linked list? A linked list is a linear data structure that is made up of a sequence of nodes.

A singly linked list is a data structure in which each node points to the next node. The head of a singly linked list points to the address of the first element of the list. It is known as a singly linked list as it has only one link pointing to its next node.

Representation of a singly linked list

A singly linked list is represented by a node consisting of data and a pointer that points to the address of the next node:

/**
 * struct node_s - singly linked list
 * @data: The data * 
 * @next: points to the next node
 *
 * Description: singly linked list node structure
 */
typedef struct node_s
{
    int data;
    struct node_s *next;
} node_t;

Operations on a singly linked list

The following operations can be performed on a singly linked list:

  • Insertion - Inserts an element in a list.

  • Deletion − Deletes an element in a list.

  • Traversal − Displays the complete list.

  • Search − Searches an element using the given key.

  • Delete − Deletes an element using the given key.

Let's look at how to perform the above operations in a singly linked list:

Insertion operation

By performing this operation we can add elements to a singly linked list.

Insertion at the beginning

In this operation, we are adding an element at the beginning of the list:

#include <stdlib.h>
#include <stdio.h>
/**
 * struct node_s - singly linked list
 * @data: The data * 
 * @next: points to the next node
 *
 * Description: singly linked list node structure
 */
typedef struct node_s
{
    int data;
    struct node_s *next;
} node_t;
/**
 * insert_at_begin - adds a new node at the beginning of a list
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/
node_t *insert_at_begin(node_t **head, int data)
{
    node_t *new;
    if (head == NULL)
        return (NULL);
    /* create a new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);
    /* add data to the new node */
    new->data = data;
    /* point head to address of new node */
    new->next = *head;    
    *head = new;
    return (new);
}
/**
 * print_list - prints all the elements of a list_t list
 * @h: list
 *
 * Return: nothing
*/
void print_list(node_t *h)
{
    while (h != NULL)
    {
        printf("%d ", h->data);
        h = h->next;
        printf("\n");
    }    
}
/**
 * main - check the code
 *
 * Return: Always 0.
 */
int main(void)
{
    node_t *head;

    head = NULL;
    insert_at_begin(&head, 1);
    insert_at_begin(&head, 2);
    insert_at_begin(&head, 3);    
    print_list(head);
    return (0);
}

Output:

3
2
1

Insert at the end

In this operation, we are adding an element at the end of the list:

#include <stdlib.h>
#include <stdio.h>
/**
 * struct node_s - singly linked list
 * @data: The data *
 * @next: points to the next node
 *
 * Description: singly linked list node structure
 */
typedef struct node_s
{
    int data;
    struct node_s *next;
} node_t;
/**
 * insert_at_begin - adds a new node at the beginning of a list
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/
node_t *insert_at_begin(node_t **head, int data)
{
    node_t *new;

    if (head == NULL)
        return (NULL);
    /* create a new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);
    /* add data to the new node */
    new->data = data;
    /* point head to address of new node */
    new->next = *head;
    *head = new;
    return (new);
}
/**
 * insert_at_end - adds a new node at the end of a ist
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/

node_t *insert_at_end(node_t **head, int data)
{
    node_t *new, *temp;

    /* check if the head pointer is NULL */
    if (head == NULL)
        return (NULL);
    /* allocate memory for the new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);

    /* assign data to the new node and set its next pointer to NULL */
    new->data = data;
    new->next = NULL;
    /* if the linked list is empty, make the new node the head */
    if (*head == NULL)
        *head = new;
    else
    {
        temp = *head;
        /* traverse the linked list to find the last node */
        while (temp->next != NULL)
            temp = temp->next;
        /* insert the new node at the end */
        temp->next = new;
    }
    /* return a pointer to the newly inserted node */
    return (new);
}
/**
 * print_list - prints all the elements of a list_t list
 * @h: list
 *
 * Return: nothing
*/
void print_list(node_t *h)
{
    while (h != NULL)
    {
        printf("%d ", h->data);
        h = h->next;
        printf("\n");
    }
}
/**
 * main - check the code
 *
 * Return: Always 0.
 */
int main(void)
{
    node_t *head;

    head = NULL;
    insert_at_begin(&head, 1);
    insert_at_begin(&head, 2);
    insert_at_begin(&head, 3);
    printf("-----------------\n");
    insert_at_end(&head, 5);
    insert_at_end(&head, 8);
    insert_at_end(&head, 13);
    print_list(head);
    return (0);
}

Output:

3 
2 
1 
-----------------
3 
2 
1 
5 
8 
13

Insert at a specified position

In this operation, we are adding an element at a specified position of the list:

#include <stdlib.h>
#include <stdio.h>
/**
 * struct node_s - singly linked list
 * @data: The data *
 * @next: points to the next node
 *
 * Description: singly linked list node structure
 */
typedef struct node_s
{
    int data;
    struct node_s *next;
} node_t;
/**
 * insert_at_begin - adds a new node at the beginning of a list
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/
node_t *insert_at_begin(node_t **head, int data)
{
    node_t *new;

    if (head == NULL)
        return (NULL);
    /* create a new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);
    /* add data to the new node */
    new->data = data;
    /* point head to address of new node */
    new->next = *head;
    *head = new;
    return (new);
}
/**
 * insert_at_end - adds a new node at the end of a ist
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/

node_t *insert_at_end(node_t **head, int data)
{
    node_t *new, *temp;

    /* check if the head pointer is NULL */
    if (head == NULL)
        return (NULL);
    /* allocate memory for the new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);

    /* assign data to the new node and set its next pointer to NULL */
    new->data = data;
    new->next = NULL;
    /* if the linked list is empty, make the new node the head */
    if (*head == NULL)
        *head = new;
    else
    {
        temp = *head;
        /* traverse the linked list to find the last node */
        while (temp->next != NULL)
            temp = temp->next;
        /* insert the new node at the end */
        temp->next = new;
    }
    /* return a pointer to the newly inserted node */
    return (new);
}
/**
 * insert_at_index - adds a new node at a specified
 * end of a list
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/
node_t *insert_at_index(node_t **head, unsigned int idx, int data)
{
    unsigned int count = 0, i = 1;
    node_t *new, *current;

    /* initialize current pointer to point to the head of the list */
    current = *head;

    /* count the number of nodes in the linked list */
    while (current)
    {
        current = current->next;
        count++;
    }

    /* check if the index is out of bounds */
    if (idx > count)
        return (NULL);

    /* allocate memory for the new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);

    /* assign data to the new node */
    new->data = data;

    /* if the index is 0, insert the new node at the beginning of the list */
    if (idx == 0)
    {
        new->next = *head;
        *head = new;
        return (new);
    }

    /* reset current pointer to point to the head of the list */
    current = *head;

    /* traverse the list to find the node before the insertion point */
    for (i = 0; i < idx - 1; i++)
        current = current->next;

    /* insert the new node at the specified index */
    new->next = current->next;
    current->next = new;

    /* return a pointer to the newly inserted node */
    return (new);
}
/**
 * print_list - prints all the elements of a list_t list
 * @h: list
 *
 * Return: nothing
*/
void print_list(node_t *h)
{
    while (h != NULL)
    {
        printf("%d ", h->data);
        h = h->next;
        printf("\n");
    }    
}
/**
 * main - check the code
 *
 * Return: Always 0.
 */
int main(void)
{
    node_t *head;

    head = NULL;
    insert_at_begin(&head, 1);
    insert_at_begin(&head, 2);
    insert_at_begin(&head, 3);
    print_list(head);
    printf("-----------------\n");
    insert_at_end(&head, 5);
    insert_at_end(&head, 8);
    insert_at_end(&head, 13);
    print_list(head);
    printf("-----------------\n");
    insert_at_index(&head, 5, 4096);        
    print_list(head);
    return (0);
}

Output:

3 
2 
1 
-----------------
3 
2 
1 
5 
8 
13 
-----------------
3 
2 
1 
5 
8 
4096 
13

Deletion operation

By performing this operation we can remove elements from a singly linked list.

Deletion at the beginning

In this operation, we are removing an element at the beginning of the list:

#include <stdlib.h>
#include <stdio.h>
/**
 * struct node_s - singly linked list
 * @data: The data *
 * @next: points to the next node
 *
 * Description: singly linked list node structure
 */
typedef struct node_s
{
    int data;
    struct node_s *next;
} node_t;
/**
 * insert_at_begin - adds a new node at the beginning of a list
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/
node_t *insert_at_begin(node_t **head, int data)
{
    node_t *new;

    if (head == NULL)
        return (NULL);
    /* create a new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);
    /* add data to the new node */
    new->data = data;
    /* point head to address of new node */
    new->next = *head;
    *head = new;
    return (new);
}
/**
 * insert_at_end - adds a new node at the end of a ist
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/

node_t *insert_at_end(node_t **head, int data)
{
    node_t *new, *temp;

    /* check if the head pointer is NULL */
    if (head == NULL)
        return (NULL);
    /* allocate memory for the new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);

    /* assign data to the new node and set its next pointer to NULL */
    new->data = data;
    new->next = NULL;
    /* if the linked list is empty, make the new node the head */
    if (*head == NULL)
        *head = new;
    else
    {
        temp = *head;
        /* traverse the linked list to find the last node */
        while (temp->next != NULL)
            temp = temp->next;
        /* insert the new node at the end */
        temp->next = new;
    }
    /* return a pointer to the newly inserted node */
    return (new);
}
/**
 * insert_at_index - adds a new node at a specified
 * end of a list
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/
node_t *insert_at_index(node_t **head, unsigned int idx, int data)
{
    unsigned int count = 0, i = 1;
    node_t *new, *current;

    /* initialize current pointer to point to the head of the list */
    current = *head;

    /* count the number of nodes in the linked list */
    while (current)
    {
        current = current->next;
        count++;
    }

    /* check if the index is out of bounds */
    if (idx > count)
        return (NULL);

    /* allocate memory for the new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);

    /* assign data to the new node */
    new->data = data;

    /* if the index is 0, insert the new node at the beginning of the list */
    if (idx == 0)
    {
        new->next = *head;
        *head = new;
        return (new);
    }

    /* reset current pointer to point to the head of the list */
    current = *head;

    /* traverse the list to find the node before the insertion point */
    for (i = 0; i < idx - 1; i++)
        current = current->next;

    /* insert the new node at the specified index */
    new->next = current->next;
    current->next = new;

    /* return a pointer to the newly inserted node */
    return (new);
}
/**
 * delete_at_begin - deletes a node at the beginning of a list
 * @head: double pointer to head of a list 
 *
 * Return: nothing
*/
void *delete_at_begin(node_t **head)
{
    node_t *temp;

    /* Check if the head pointer or the list is empty */
    if ((*head)->next == NULL)
    {
        /* If only one node is present, set head to NULL and free the memory */
        *head = NULL;
        free(temp);
    }

    /* Store the address of the current head node in temp */
    temp = *head;

    /* Update the head pointer to point to the next node */
    *head = (*head)->next;

    /* Free the memory allocated to the previous head node */
    free(temp);
}
/**
 * print_list - prints all the elements of a list_t list
 * @h: list
 *
 * Return: nothing
*/
void print_list(node_t *h)
{
    while (h != NULL)
    {
        printf("%d ", h->data);
        h = h->next;
        printf("\n");
    }    
}
/**
 * main - check the code
 *
 * Return: Always 0.
 */
int main(void)
{
    node_t *head;

    head = NULL;
    insert_at_begin(&head, 1);
    insert_at_begin(&head, 2);
    insert_at_begin(&head, 3);
    print_list(head);
    printf("-----------------\n");
    insert_at_end(&head, 5);
    insert_at_end(&head, 8);
    insert_at_end(&head, 13);
    print_list(head);
    printf("-----------------\n");
    insert_at_index(&head, 5, 4096);        
    print_list(head);
    printf("-----------------\n");
    delete_at_begin(&head);
    delete_at_begin(&head);
    delete_at_begin(&head);
    print_list(head);

    return (0);
}

Output:

3 
2 
1 
-----------------
3 
2 
1 
5 
8 
13 
-----------------
3 
2 
1 
5 
8 
4096 
13 
-----------------
5 
8 
4096 
13

Delete at the end

In this operation, we are removing an element at the end of the list:

#include <stdlib.h>
#include <stdio.h>
/**
 * struct node_s - singly linked list
 * @data: The data *
 * @next: points to the next node
 *
 * Description: singly linked list node structure
 */
typedef struct node_s
{
    int data;
    struct node_s *next;
} node_t;
/**
 * insert_at_begin - adds a new node at the beginning of a list
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/
node_t *insert_at_begin(node_t **head, int data)
{
    node_t *new;

    if (head == NULL)
        return (NULL);
    /* create a new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);
    /* add data to the new node */
    new->data = data;
    /* point head to address of new node */
    new->next = *head;
    *head = new;
    return (new);
}
/**
 * insert_at_end - adds a new node at the end of a ist
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/

node_t *insert_at_end(node_t **head, int data)
{
    node_t *new, *temp;

    /* check if the head pointer is NULL */
    if (head == NULL)
        return (NULL);
    /* allocate memory for the new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);

    /* assign data to the new node and set its next pointer to NULL */
    new->data = data;
    new->next = NULL;
    /* if the linked list is empty, make the new node the head */
    if (*head == NULL)
        *head = new;
    else
    {
        temp = *head;
        /* traverse the linked list to find the last node */
        while (temp->next != NULL)
            temp = temp->next;
        /* insert the new node at the end */
        temp->next = new;
    }
    /* return a pointer to the newly inserted node */
    return (new);
}
/**
 * insert_at_index - adds a new node at a specified
 * end of a list
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/
node_t *insert_at_index(node_t **head, unsigned int idx, int data)
{
    unsigned int count = 0, i = 1;
    node_t *new, *current;

    /* initialize current pointer to point to the head of the list */
    current = *head;

    /* count the number of nodes in the linked list */
    while (current)
    {
        current = current->next;
        count++;
    }

    /* check if the index is out of bounds */
    if (idx > count)
        return (NULL);

    /* allocate memory for the new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);

    /* assign data to the new node */
    new->data = data;

    /* if the index is 0, insert the new node at the beginning of the list */
    if (idx == 0)
    {
        new->next = *head;
        *head = new;
        return (new);
    }

    /* reset current pointer to point to the head of the list */
    current = *head;

    /* traverse the list to find the node before the insertion point */
    for (i = 0; i < idx - 1; i++)
        current = current->next;

    /* insert the new node at the specified index */
    new->next = current->next;
    current->next = new;

    /* return a pointer to the newly inserted node */
    return (new);
}
/**
 * delete_at_begin - deletes a node at the beginning of a list
 * @head: double pointer to head of a list 
 *
 * Return: nothing
*/
void *delete_at_begin(node_t **head)
{
    node_t *temp;

    /* Check if the head pointer or the list is empty */
    if ((*head)->next == NULL)
    {
        /* If only one node is present, set head to NULL and free the memory */
        *head = NULL;
        free(temp);
    }

    /* Store the address of the current head node in temp */
    temp = *head;

    /* Update the head pointer to point to the next node */
    *head = (*head)->next;

    /* Free the memory allocated to the previous head node */
    free(temp);
}
/**
 * delete_at_end - deletes a node at the end of a list
 * @head: double pointer to head of a list 
 *
 * Return: nothing
*/
void *delete_at_end(node_t **head)
{
    node_t *prev, *temp;

    /* check if the head pointer or the list is empty */
    if (*head == NULL)
        return (NULL);

    /* initialize pointers to traverse the list */
    prev = NULL;
    temp = *head;

    /* traverse the list until the last node is reached */
    while (temp->next != NULL)
    {
        prev = temp;
        temp = temp->next;
    }

    /* if the last node is the head node */
    if (temp == *head)
        *head = NULL;
    else
    /* Update the previous node's next pointer to NULL */
        prev->next = NULL;

    /* Free the memory allocated to the last node */
    free(temp);
}
/**
 * print_list - prints all the elements of a list_t list
 * @h: list
 *
 * Return: nothing
*/
void print_list(node_t *h)
{
    while (h != NULL)
    {
        printf("%d ", h->data);
        h = h->next;
        printf("\n");
    }    
}
/**
 * main - check the code
 *
 * Return: Always 0.
 */
int main(void)
{
    node_t *head;

    head = NULL;
    insert_at_begin(&head, 1);
    insert_at_begin(&head, 2);
    insert_at_begin(&head, 3);
    print_list(head);
    printf("-----------------\n");
    insert_at_end(&head, 5);
    insert_at_end(&head, 8);
    insert_at_end(&head, 13);
    print_list(head);
    printf("-----------------\n");
    insert_at_index(&head, 5, 4096);        
    print_list(head);
    printf("-----------------\n");
    delete_at_begin(&head);
    delete_at_begin(&head);
    delete_at_begin(&head);
    print_list(head);
    printf("-----------------\n");
    delete_at_end(&head);
    delete_at_end(&head);
    print_list(head);

    return (0);
}

Output:

3 
2 
1 
-----------------
3 
2 
1 
5 
8 
13 
-----------------
3 
2 
1 
5 
8 
4096 
13 
-----------------
5 
8 
4096 
13 
-----------------
5 
8

Delete at a specified position

In this operation, we are removing an element at a specified position of the list:

#include <stdlib.h>
#include <stdio.h>
/**
 * struct node_s - singly linked list
 * @data: The data *
 * @next: points to the next node
 *
 * Description: singly linked list node structure
 */
typedef struct node_s
{
    int data;
    struct node_s *next;
} node_t;
/**
 * insert_at_begin - adds a new node at the beginning of a list
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/
node_t *insert_at_begin(node_t **head, int data)
{
    node_t *new;

    if (head == NULL)
        return (NULL);
    /* create a new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);
    /* add data to the new node */
    new->data = data;
    /* point head to address of new node */
    new->next = *head;
    *head = new;
    return (new);
}
/**
 * insert_at_end - adds a new node at the end of a ist
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/

node_t *insert_at_end(node_t **head, int data)
{
    node_t *new, *temp;

    /* check if the head pointer is NULL */
    if (head == NULL)
        return (NULL);
    /* allocate memory for the new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);

    /* assign data to the new node and set its next pointer to NULL */
    new->data = data;
    new->next = NULL;
    /* if the linked list is empty, make the new node the head */
    if (*head == NULL)
        *head = new;
    else
    {
        temp = *head;
        /* traverse the linked list to find the last node */
        while (temp->next != NULL)
            temp = temp->next;
        /* insert the new node at the end */
        temp->next = new;
    }
    /* return a pointer to the newly inserted node */
    return (new);
}
/**
 * insert_at_index - adds a new node at a specified
 * end of a list
 * @head: double pointer to head of a list
 * @data: data of the list
 *
 * Return: address of the new element, otherwise NULL
*/
node_t *insert_at_index(node_t **head, unsigned int idx, int data)
{
    unsigned int count = 0, i = 1;
    node_t *new, *current;

    /* initialize current pointer to point to the head of the list */
    current = *head;

    /* count the number of nodes in the linked list */
    while (current)
    {
        current = current->next;
        count++;
    }

    /* check if the index is out of bounds */
    if (idx > count)
        return (NULL);

    /* allocate memory for the new node */
    new = malloc(sizeof(node_t));
    if (new == NULL)
        return (NULL);

    /* assign data to the new node */
    new->data = data;

    /* if the index is 0, insert the new node at the beginning of the list */
    if (idx == 0)
    {
        new->next = *head;
        *head = new;
        return (new);
    }

    /* reset current pointer to point to the head of the list */
    current = *head;

    /* traverse the list to find the node before the insertion point */
    for (i = 0; i < idx - 1; i++)
        current = current->next;

    /* insert the new node at the specified index */
    new->next = current->next;
    current->next = new;

    /* return a pointer to the newly inserted node */
    return (new);
}
/**
 * delete_at_begin - deletes a node at the beginning of a list
 * @head: double pointer to head of a list 
 *
 * Return: nothing
*/
void *delete_at_begin(node_t **head)
{
    node_t *temp;

    /* Check if the head pointer or the list is empty */
    if ((*head)->next == NULL)
    {
        /* If only one node is present, set head to NULL and free the memory */
        *head = NULL;
        free(temp);
    }

    /* Store the address of the current head node in temp */
    temp = *head;

    /* Update the head pointer to point to the next node */
    *head = (*head)->next;

    /* Free the memory allocated to the previous head node */
    free(temp);
}
/**
 * delete_at_end - deletes a node at the end of a list
 * @head: double pointer to head of a list 
 *
 * Return: nothing
*/
void *delete_at_end(node_t **head)
{
    node_t *prev, *temp;

    /* check if the head pointer or the list is empty */
    if (*head == NULL)
        return (NULL);

    /* initialize pointers to traverse the list */
    prev = NULL;
    temp = *head;

    /* traverse the list until the last node is reached */
    while (temp->next != NULL)
    {
        prev = temp;
        temp = temp->next;
    }

    /* if the last node is the head node */
    if (temp == *head)
        *head = NULL;
    else
    /* update the previous node's next pointer to NULL */
        prev->next = NULL;

    /* free the memory allocated to the last node */
    free(temp);
}
/**
 * delete_at_idx - deletes a node at a specified postion
 * of a list
 * @head: double pointer to head of a list 
 *
 * Return: nothing
*/
void *delete_at_idx(node_t **head, unsigned int idx)
{
    node_t *temp, *to_delete;
    unsigned int i = 0;

    /* check if the head pointer or the list is empty */
    if (*head == NULL)
        return (NULL);

    /* special case: If index is 0, delete the head node */
    if (idx == 0)
    {
        to_delete = *head;
        *head = (*head)->next;
        free(to_delete);
        return (NULL);
    }

    /* traverse the list to find the node before the index to delete */
    temp = *head;
    while (i < idx - 1 && temp->next != NULL)
    {
        temp = temp->next;
        i++;
    }

    /* if index is out of bounds or the next node is NULL, return */
    if (temp->next == NULL)
        return (NULL);

    /* store the node to be deleted and update pointers to skip it */
    to_delete = temp->next;
    temp->next = to_delete->next;

    /* free the memory allocated to the deleted node */
    free(to_delete);
}
/**
 * print_list - prints all the elements of a list_t list
 * @h: list
 *
 * Return: nothing
*/
void print_list(node_t *h)
{
    while (h != NULL)
    {
        printf("%d ", h->data);
        h = h->next;
        printf("\n");
    }    
}
/**
 * main - check the code
 *
 * Return: Always 0.
 */
int main(void)
{
    node_t *head;

    head = NULL;
    insert_at_begin(&head, 1);
    insert_at_begin(&head, 2);
    insert_at_begin(&head, 3);
    print_list(head);
    printf("-----------------\n");
    insert_at_end(&head, 5);
    insert_at_end(&head, 8);
    insert_at_end(&head, 13);
    print_list(head);
    printf("-----------------\n");
    insert_at_index(&head, 5, 4096);        
    print_list(head);
    printf("-----------------\n");
    delete_at_begin(&head);
    delete_at_begin(&head);
    delete_at_begin(&head);
    print_list(head);
    printf("-----------------\n");
    delete_at_end(&head);
    delete_at_end(&head);
    print_list(head);
    printf("-----------------\n");
    delete_at_idx(&head, 1);    
    print_list(head);

    return (0);
}

Traversal operation

Traversing a singly linked list is where you visit each node of a singly linked list until the end is reached. By doing so you can then display the items.

/**
 * print_list - prints all the elements of a list_t list
 * @h: list
 *
 * Return: nothing
*/
void print_list(node_t *h)
{
    /* traverse the list until the end is reached (NULL) */
    while (h != NULL)
    {
        /* print the data of the current node */
        printf("%d ", h->data);

        /* move to the next node */
        h = h->next;

        /* print a newline after printing each node's data */
        printf("\n");
    }
}

Output:

3 
2 
1 
-----------------
3 
2 
1 
5 
8 
13 
-----------------
3 
2 
1 
5 
8 
4096 
13 
-----------------
5 
8 
4096 
13 
-----------------
5 
8 
-----------------
5

Challenge: Try to implement the other operations not implemented in this article and find their time and space complexities.

Happy coding!

More from this blog

Clifford Mapesa

34 posts

Hi there, I'm Clifford Mapesa, a full-stack software engineer. I'm passionate about building great experiences using software.