Open In App

How to Create a Doubly Linked List in C?

Last Updated : 06 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

A doubly linked list is a type of linked list in which each node has two links. The first link points to the previous node in the list while the second link points to the next node in the list. In other words, navigation in a doubly linked list is possible from both sides, from the front as well as the back. In this article, we will learn how to create a doubly linked list in C.

What is a Doubly Linked List?

In a singly linked list, each node has only one link which points to the node next to it. For this reason, we can traverse it from one side only and we cannot traverse back and forth. To solve this problem doubly linked list is used where each node contains a link to the next as well as the previous node.

doubly linked list

How We Can Create a Doubly Linked List in C?

To create a Doubly Linked List in C, you need to define a structure that represents each node in the list. Each node should contain pointers to the previous and next nodes. Then, you can define functions to perform operations such as insertion, deletion, and traversal on the doubly linked list.

1. Representation

The doubly linked list node can be represented as a structure in C language. The below structure represents the minimal doubly linked list:

typedef struct node {
    int data;
    struct node* next;
    struct node* prev;
} Node;

Here,

  • data: data field of the node.
  • next: pointer to the next node.
  • prev: pointer to the prev node.

The nodes at the ends (i.e. does not have a previous or next node) will be set as NULL.

We can then use this data type with malloc() to dynamically create the instances of the doubly linked list node and then join them inside insertion operations.

The whole doubly linked list will be represented as the pointer to the head node (i.e. starting node) as all the nodes can be traversed using this node. We can also maintain a pointer to the end node for our convenience.

2. Basic Operations

The basic operations that are performed on the double linked list in this program are as follows:-

Operation

Description

Time Complexity

Space Complexity

Insert_at_head

Adding an element to the beginning of the doubly linked list.

O(1)

O(1)

Delete_at_head

Deleting an element from the beginning of the doubly linked list.

O(1)

O(1)

Insert_at_tail

To add an element to the end of the doubly linked list.

O(1), if we have pointer to tail, otherwise O(N).

O(1)

Delete_at_tail

Delete an element from the end of the doubly linked list.

O(1), if we have pointer to tail, otherwise O(N).

O(1)

Display forward

To display the entire doubly linked list in a forward manner.

O(N)

O(1)

Display backwards

To display the entire doubly linked list in a backward manner.

O(N)

O(1)

C Program to Create a Doubly Linked List in C

C




// C Program  to illustrate how to create a doubly linked
// list
#include <stdio.h>
#include <stdlib.h>
  
// doubly linked list node template
struct node {
    int data;
    struct node* next;
    struct node* prev;
};
  
// creating a pointer to head and tail of the linked list
struct node* head = NULL;
struct node* tail = NULL;
  
// create a new node with the given data and return a
// pointer to it
struct node* create_node(int data)
{
    struct node* new_node
        = (struct node*)malloc(sizeof(struct node));
    new_node->data = data;
    new_node->next = NULL;
    new_node->prev = NULL;
    return new_node;
}
  
// insert a node at the beginning of the list
void insert_at_head(int data)
{
    struct node* new_node = create_node(data);
    if (head == NULL) {
        head = new_node;
        tail = new_node;
    }
    else {
        new_node->next = head;
        head->prev = new_node;
        head = new_node;
    }
}
  
// insert a node at the end of the list
void insert_at_tail(int data)
{
    struct node* new_node = create_node(data);
    if (tail == NULL) {
        head = new_node;
        tail = new_node;
    }
    else {
        new_node->prev = tail;
        tail->next = new_node;
        tail = new_node;
    }
}
  
// delete the node at the beginning of the list
void delete_at_head()
{
    if (head == NULL) {
        return;
    }
    struct node* temp = head;
    if (head == tail) {
        head = NULL;
        tail = NULL;
    }
    else {
        head = head->next;
        head->prev = NULL;
    }
    free(temp);
}
  
// delete the node at the end of the list
void delete_at_tail()
{
    if (tail == NULL) {
        return;
    }
    struct node* temp = tail;
    if (head == tail) {
        head = NULL;
        tail = NULL;
    }
    else {
        tail = tail->prev;
        tail->next = NULL;
    }
    free(temp);
}
  
// display the list in forward direction
void display_forward()
{
    struct node* current = head;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");
}
  
// display the list in backward direction
void display_backward()
{
    struct node* current = tail;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->prev;
    }
    printf("\n");
}
  
// Driver code to test the doubly linked list
int main()
{
    insert_at_head(10);
    insert_at_head(20);
    insert_at_tail(30);
    display_forward(); // expected output: 20 10 30
    display_backward(); // expected output: 30 10 20
    delete_at_head();
    delete_at_tail();
    display_forward(); // expected output: 10
    display_backward(); // expected output: 10
  
    return 0;
}


Output

20 10 30 
30 10 20 
10 
10 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads