Doubly Linked List with Implementation of Code – DSA

doubly linked list
  • One drawback of a singly linked list is that it can only be traversed singly. Many apps need you to browse through a list’s parts back and forth. 
  • Making a double-linked list is a helpful improvement over a singly linked list. 
  • Unlike singly linked lists, which have pointers pointing in only one direction, doubly linked lists have pointers pointing to both the previous and next nodes.
  • A doubly linked list’s primary benefit is that it allows for both direction traversal and searching of the list.
  • Every node in this linked list has three fields.
  • One is used to hold data, and the others are self-referential pointers that point to the nodes in the list that come before and after it. 

Doubly Linked List Operations:

  1. Insertion operation
  2. Deletion operation

Insertion operation

Three cases exist for an element to be added to the list.

  1. Insertion at the beginning of DLL
  2. Insertion at the end of the DLL
  3. Insertion at a specific location in the DLL

Case 1: Insertion at the beginning of DLL

insertion at beginning in the doubly linked list
  • Construct a new node, new_node, using the provided data, and assign null to its previous pointer, new_node->prev = NULL.
  • New_node->next = head; this sets the next pointer of new_node to the current head.
  • Head->prev = new_node is the updated reference to the previous head if the linked list is not empty.
  • As the head of the revised linked list, return new_node.

Implementation of the Program in 4 languages using the above approach

class Node:
    def __init__(self, data):
        self.data = data  # Store the data in the node
        self.prev = None  # Pointer to the previous node
        self.next = None  # Pointer to the next node
class DoublyLinkedList:
    def __init__(self):
        self.head = None  # Initialize the head of the list
    def push(self, new_data):
        """Inserts a new node with 'new_data' at the beginning of the doubly linked list."""
        # 1. Allocate memory for the new node
        new_node = Node(new_data)
        # 2. If the list is empty, make the new node both head and tail
        if self.head is None:
            self.head = new_node
            return  
        # 3. Set the previous pointer of the current head to the new node
        self.head.prev = new_node
        # 4. Make the next of the new node as the head
        new_node.next = self.head
        # 5. Move the head to point to the new node
        self.head = new_node
    def printList(self, node):
        """Prints the data of all nodes in the doubly linked list."""
        while node is not None:
            print(node.data, end=" ")
            last = node
            node = node.next
# Example usage:
dll = DoublyLinkedList()
dll.push(2)
dll.push(4)
dll.push(8)
dll.push(10)
print("Created DLL is: ")
dll.printList(dll.head)  # Output: 10 8 4 2 
#include <iostream>
using namespace std;
// Node structure for a doubly linked list
struct Node {
    int data;
    Node* prev;
    Node* next;
};
class DoublyLinkedList {
public:
    Node* head; // Pointer to the head of the list
    DoublyLinkedList() : head(nullptr) {} // Constructor
    // Function to insert a new node at the beginning
    void push(int new_data) {
        // 1. Allocate memory for the new node
        Node* new_node = new Node;
        // 2. Put in the data
        new_node->data = new_data;
        // 3. Make next of new node as head and previous as NULL
        new_node->next = head;
        new_node->prev = nullptr;
        // 4. Change prev of head node to new node 
        if (head != nullptr) {
            head->prev = new_node;
        }
        // 5. Move the head to point to the new node
        head = new_node;
    }
    // Function to print the doubly linked list
    void printList(Node* node) {
        while (node != nullptr) {
            cout << node->data << " ";
            node = node->next;
        }
        cout << endl;
    }
};
// Example usage
int main() {
    DoublyLinkedList dll;
    dll.push(2);
    dll.push(4);
    dll.push(8);
    dll.push(10);
    cout << "Created DLL is: ";
    dll.printList(dll.head); // Output: 10 8 4 2
    return 0;
}
class Node {
    int data;
    Node prev;
    Node next;
    // Constructor to create a new node
    Node(int d) { 
        data = d; 
        prev = null; 
        next = null; 
    }
}
class DoublyLinkedList {
    Node head; // Head of the list
    // Function to insert a new node at the beginning of the Doubly Linked List
    public void push(int new_data) {
        // 1. Allocate the Node & put in the data
        Node new_Node = new Node(new_data);
        // 2. Make next of new node as head and previous as NULL
        new_Node.next = head;
        new_Node.prev = null;
        // 3. Change prev of head node to new node 
        if (head != null) {
            head.prev = new_Node;
        }
        // 4. Move the head to point to the new node
        head = new_Node;
    }
    // Function to print nodes in a given doubly linked list 
    public void printList(Node node) {
        while (node != null) {
            System.out.print(node.data + " ");
            node = node.next;
        }
        System.out.println();
    }
    public static void main(String[] args) {
        DoublyLinkedList dll = new DoublyLinkedList();
        dll.push(2);
        dll.push(4);
        dll.push(8);
        dll.push(10);
        System.out.print("Created DLL is: ");
        dll.printList(dll.head); // Output: 10 8 4 2
    }
}
#include <stdio.h>
#include <stdlib.h>
// Structure of a node in the Doubly Linked List
struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
};
// Function to insert a new node at the beginning of the Doubly Linked List
void push(struct Node** head_ref, int new_data) {
    // 1. Allocate memory for the new node
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
    // 2. Put in the data
    new_node->data = new_data;
    // 3. Make next of new node as head and previous as NULL
    new_node->next = (*head_ref);
    new_node->prev = NULL;
    // 4. Change prev of head node to new node
    if ((*head_ref) != NULL) {
        (*head_ref)->prev = new_node;
    }
    // 5. Move the head to point to the new node
    (*head_ref) = new_node;
}
// Function to print nodes in a given doubly linked list
void printList(struct Node* node) {
    while (node != NULL) {
        printf("%d ", node->data);
        node = node->next;
    }
    printf("\n");
}
int main() {
    struct Node* head = NULL; // Start with an empty list
    push(&head, 2);
    push(&head, 4);
    push(&head, 8);
    push(&head, 10);
    printf("Created DLL is: ");
    printList(head); // Output: 10 8 4 2
    return 0;
}

Output:

Created DLL is: 
10 8 4 2

Case 2: Insertion at the end of the DLL

insertion at end in the doubly linked list
  • The following procedures can be used to add a new node to the end of the doubly linked list:
    • A new node should have memory allocated to it and its data field should be given the given value.
    • Set the new node’s next pointer’s initial value to nullptr.
  • If the list is empty:
    • Assign nullptr to the new node’s prior pointer.
    • To point to the new node, update the head pointer.
  • Should the list not be empty:
    • To get the last node, go through the list beginning at the head.
    • Assign the new node’s pointer to the previous node’s next pointer.
    • Make sure the new node’s previous pointer points to the final node.

Implementation of the Program in 4 languages using the above approach

class Node:
    def __init__(self, data):
        self.data = data  # Store the data in the node
        self.prev = None  # Pointer to the previous node
        self.next = None  # Pointer to the next node
class DoublyLinkedList:
    def __init__(self):
        self.head = None  # Initialize the head of the list
    def append(self, new_data):
        """Inserts a new node with 'new_data' at the end of the doubly linked list."""
        # 1. Allocate memory for the new node
        new_node = Node(new_data)
        # 2. If the list is empty, make the new node the head
        if self.head is None:
            self.head = new_node
            return
        # 3. Traverse to the last node
        last = self.head
        while last.next:
            last = last.next
        # 4. Change the next of the last node
        last.next = new_node
        # 5. Make the last node the previous of the new node
        new_node.prev = last
    def printList(self, node):
        """Prints the data of all nodes in the doubly linked list."""
        while node:
            print(node.data, end=" ")
            last = node
            node = node.next
# Example usage:
dll = DoublyLinkedList()
dll.append(2)
dll.append(4)
dll.append(8)
dll.append(10)
print("Created DLL is: ")
dll.printList(dll.head)  # Output: 2 4 8 10 
#include <iostream>
using namespace std;
// Node structure for a doubly linked list
struct Node {
    int data;
    Node* prev;
    Node* next;
};
class DoublyLinkedList {
public:
    Node* head; // Pointer to the head of the list
    DoublyLinkedList() : head(nullptr) {} // Constructor
    // Function to insert a new node at the end
    void append(int new_data) {
        // 1. Allocate memory for the new node
        Node* new_node = new Node;
        // 2. Put in the data
        new_node->data = new_data;
        // 3. This new node is going to be the last node, so make next of it as NULL
        new_node->next = nullptr;
        // 4. If the Linked List is empty, then make the new node as head
        if (head == nullptr) {
            new_node->prev = nullptr; 
            head = new_node;
            return;
        }
        // 5. Else traverse till the last node
        Node* last = head;
        while (last->next != nullptr) {
            last = last->next;
        }
        // 6. Change the next of the last node
        last->next = new_node;
        // 7. Make the last node as previous of the new node
        new_node->prev = last;
    }
    // Function to print the doubly linked list
    void printList(Node* node) {
        while (node != nullptr) {
            cout << node->data << " ";
            node = node->next;
        }
        cout << endl;
    }
};
// Example usage
int main() {
    DoublyLinkedList dll;
    dll.append(2);
    dll.append(4);
    dll.append(8);
    dll.append(10);
    cout << "Created DLL is: ";
    dll.printList(dll.head); // Output: 2 4 8 10
    return 0;
}
class Node {
    int data;
    Node prev;
    Node next;
    // Constructor to create a new node
    Node(int d) { 
        data = d; 
        prev = null; 
        next = null; 
    }
}
class DoublyLinkedList {
    Node head; // Head of the list
    // Function to insert a new node at the end of the Doubly Linked List
    public void append(int new_data) {
        // 1. Allocate the Node & put in the data
        Node new_node = new Node(new_data);
        // 2. This new node is going to be the last node, so make next of it as null
        new_node.next = null;
        // 3. If the Linked List is empty, then make the new node as head
        if (head == null) {
            new_node.prev = null;
            head = new_node;
            return;
        }
        // 4. Else traverse till the last node
        Node last = head;
        while (last.next != null)
            last = last.next;
        // 5. Change the next of the last node
        last.next = new_node;
        // 6. Make last node as previous of new node 
        new_node.prev = last;
    }
    // Function to print nodes in a given doubly linked list 
    public void printList(Node node) {
        while (node != null) {
            System.out.print(node.data + " ");
            node = node.next;
        }
        System.out.println();
    }
    public static void main(String[] args) {
        DoublyLinkedList dll = new DoublyLinkedList();
        dll.append(2);
        dll.append(4);
        dll.append(8);
        dll.append(10);
        System.out.print("Created DLL is: ");
        dll.printList(dll.head); // Output: 2 4 8 10 
    }
}
#include <stdio.h>
#include <stdlib.h>
// Structure of a node in the Doubly Linked List
struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
};
// Function to insert a new node at the end of the Doubly Linked List
void append(struct Node** head_ref, int new_data) {
    // 1. Allocate memory for the new node
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
    // 2. Put in the data
    new_node->data = new_data;
    // 3. This new node is going to be the last node, so make next of it as NULL
    new_node->next = NULL;
    // 4. If the Linked List is empty, then make the new node as head
    if ((*head_ref) == NULL) {
        new_node->prev = NULL;
        (*head_ref) = new_node;
        return;
    }
    // 5. Else traverse till the last node
    struct Node* last = (*head_ref);
    while (last->next != NULL) {
        last = last->next;
    }
    // 6. Change the next of the last node
    last->next = new_node;
    // 7. Make the last node as previous of the new node
    new_node->prev = last;
}
// Function to print nodes in a given doubly linked list
void printList(struct Node* node) {
    while (node != NULL) {
        printf("%d ", node->data);
        node = node->next;
    }
    printf("\n");
}
int main() {
    struct Node* head = NULL; // Start with an empty list
    append(&head, 2);
    append(&head, 4);
    append(&head, 8);
    append(&head, 10);
    printf("Created DLL is: ");
    printList(head); // Output: 2 4 8 10 
    return 0;
}

Output:

Created DLL is: 
2 4 8 10

Case 3: Insertion at a specific location in the DLL

insertion at specific location in the doubly linked list
  • To add a new node at a certain location,
  • Make a new node, put it at the head of the linked list, and return it if position = 1.
  • If not, go through the list until you get the node at position-1, say curr.
  • Create a new node called new_node with the provided data if the location is valid.
  • New_node->next = curr->next and new_node->prior = curr update the next pointer of the new node to the next of the current node and the prev pointer of the new node to the current node.
  • Likewise, change curr->next = new_node, the current node’s next pointer, to refer to the new node.
  • Update the prev pointer of the new nodes adjacent to the latest node, new_node->next->prev = new_node, if the new node is not the final node.

Implementation of the Program in 4 languages using the above approach

class Node:
    def __init__(self, data):
        self.data = data
        self.prev = None
        self.next = None
class DoublyLinkedList:
    def __init__(self):
        self.head = None
    def insert_at_position(self, new_data, position):
        """Inserts a new node with 'new_data' at the specified 'position' in the doubly linked list."""
        # 1. Create the new node
        new_node = Node(new_data)
        # 2. If the list is empty, make the new node the head
        if self.head is None:
            self.head = new_node
            return
        # 3. If inserting at position 0 (beginning), handle it separately
        if position == 0:
            new_node.next = self.head
            self.head.prev = new_node
            self.head = new_node
            return
        # 4. Traverse to the node before the desired position
        temp = self.head
        count = 0
        while temp is not None and count < position - 1:
            temp = temp.next
            count += 1
        # 5. If the position is beyond the list length, insert at the end
        if temp is None:
            self.append(new_data)  # Use the append method to insert at the end
            return
        # 6. Insert the new node at the desired position
        new_node.next = temp.next
        new_node.prev = temp
        if temp.next is not None:
            temp.next.prev = new_node
        temp.next = new_node
    def append(self, new_data):
        """Inserts a new node at the end of the doubly linked list."""
        new_node = Node(new_data)
        if self.head is None:
            self.head = new_node
            return
        last = self.head
        while last.next:
            last = last.next
        last.next = new_node
        new_node.prev = last
    def printList(self, node):
        """Prints the data of all nodes in the doubly linked list."""
        while node:
            print(node.data, end=" ")
            node = node.next
# Example usage:
dll = DoublyLinkedList()
dll.append(1)
dll.append(3)
dll.append(4)
dll.insert_at_position(2, 1)  # Insert 2 at position 1
dll.printList(dll.head)  # Output: 1 2 3 4
#include <iostream>
using namespace std;
// Node structure for a doubly linked list
struct Node {
    int data;
    Node* prev;
    Node* next;
};
class DoublyLinkedList {
public:
    Node* head; // Pointer to the head of the list
    DoublyLinkedList() : head(nullptr) {} // Constructor
    // Function to insert a new node at the end
    void append(int new_data) {
        // 1. Allocate memory for the new node
        Node* new_node = new Node;
        // 2. Put in the data
        new_node->data = new_data;
        // 3. This new node is going to be the last node, so make next of it as NULL
        new_node->next = nullptr;
        // 4. If the Linked List is empty, then make the new node as head
        if (head == nullptr) {
            new_node->prev = nullptr;
            head = new_node;
            return;
        }
        // 5. Else traverse till the last node
        Node* last = head;
        while (last->next != nullptr) {
            last = last->next;
        }
        // 6. Change the next of the last node
        last->next = new_node;
        // 7. Make the last node as previous of the new node
        new_node->prev = last;
    }
    // Function to insert a new node at a given position
    void insertAtPosition(int new_data, int position) {
        // 1. Allocate memory for the new node
        Node* new_node = new Node;
        // 2. Put in the data
        new_node->data = new_data;
        // 3. If the linked list is empty, make the new node as head
        if (head == nullptr) {
            new_node->prev = nullptr;
            head = new_node;
            return;
        }
        // 4. If the position is 0, handle it like inserting at the beginning
        if (position == 0) {
            new_node->next = head;
            new_node->prev = nullptr;
            head->prev = new_node;
            head = new_node;
            return;
        }
        // 5. Else traverse till the position - 1 node
        Node* temp = head;
        for (int i = 0; i < position - 1 && temp != nullptr; i++) {
            temp = temp->next;
        }
        // 6. If the position is more than the number of nodes, insert at the end
        if (temp == nullptr) {
            append(new_data);
            return;
        }
        // 7. Adjust the pointers to insert the new node
        new_node->next = temp->next;
        new_node->prev = temp;
        if (temp->next != nullptr) {
            temp->next->prev = new_node;
        }
        temp->next = new_node;
    }
    // Function to print the doubly linked list
    void printList(Node* node) {
        while (node != nullptr) {
            cout << node->data << " ";
            node = node->next;
        }
        cout << endl;
    }
};
// Example usage
int main() {
    DoublyLinkedList dll;
    dll.append(1);
    dll.append(3);
    dll.append(4);
    dll.insertAtPosition(2, 1); // Insert 2 at position 1
    cout << "Created DLL is: ";
    dll.printList(dll.head); // Output: 1 2 3 4
    return 0;
}
class Node {
    int data;
    Node prev;
    Node next;
    // Constructor to create a new node
    Node(int d) { 
        data = d; 
        prev = null; 
        next = null; 
    }
}
class DoublyLinkedList {
    Node head; // Head of the list
    // Function to insert a new node at the end of the Doubly Linked List
    public void append(int new_data) {
        // 1. Allocate the Node & put in the data
        Node new_node = new Node(new_data);
        // 2. This new node is going to be the last node, so make next of it as null
        new_node.next = null;
        // 3. If the Linked List is empty, then make the new node as head
        if (head == null) {
            new_node.prev = null;
            head = new_node;
            return;
        }
        // 4. Else traverse till the last node
        Node last = head;
        while (last.next != null)
            last = last.next;
        // 5. Change the next of the last node
        last.next = new_node;
        // 6. Make last node as previous of new node 
        new_node.prev = last;
    }
    // Function to insert a new node at a given position
    public void insertAtPosition(int new_data, int position) {
        // 1. Allocate the Node & put in the data
        Node new_node = new Node(new_data);
        // 2. If the Linked List is empty, then make the new node as head
        if (head == null) {
            new_node.prev = null;
            head = new_node;
            return;
        }
        // 3. If the position is 0, handle it like inserting at the beginning
        if (position == 0) {
            new_node.next = head;
            new_node.prev = null;
            head.prev = new_node;
            head = new_node;
            return;
        }
        // 4. Else traverse till the position - 1 node
        Node temp = head;
        for (int i = 0; i < position - 1 && temp != null; i++) {
            temp = temp.next;
        }
        // 5. If the position is more than the number of nodes, insert at the end
        if (temp == null) {
            append(new_data);
            return;
        }
        // 6. Adjust the pointers to insert the new node
        new_node.next = temp.next;
        new_node.prev = temp;
        if (temp.next != null) {
            temp.next.prev = new_node;
        }
        temp.next = new_node;
    }
    // Function to print nodes in a given doubly linked list 
    public void printList(Node node) {
        while (node != null) {
            System.out.print(node.data + " ");
            node = node.next;
        }
        System.out.println();
    }
    public static void main(String[] args) {
        DoublyLinkedList dll = new DoublyLinkedList();
        dll.append(1);
        dll.append(3);
        dll.append(4);
        dll.insertAtPosition(2, 1); // Insert 2 at position 1
        System.out.print("Created DLL is: ");
        dll.printList(dll.head); // Output: 1 2 3 4 
    }
}
#include <stdio.h>
#include <stdlib.h>
// Structure of a node in the Doubly Linked List
struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
};
// Function to insert a new node at the end of the Doubly Linked List
void append(struct Node** head_ref, int new_data) {
    // 1. Allocate memory for the new node
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
    // 2. Put in the data
    new_node->data = new_data;
    // 3. This new node is going to be the last node, so make next of it as NULL
    new_node->next = NULL;
    // 4. If the Linked List is empty, then make the new node as head
    if ((*head_ref) == NULL) {
        new_node->prev = NULL;
        (*head_ref) = new_node;
        return;
    }
    // 5. Else traverse till the last node
    struct Node* last = (*head_ref);
    while (last->next != NULL)
        last = last->next;
    // 6. Change the next of the last node
    last->next = new_node;
    // 7. Make last node as previous of new node 
    new_node->prev = last;
}
// Function to insert a new node at a given position
void insertAtPosition(struct Node** head_ref, int new_data, int position) {
    // 1. Allocate memory for the new node
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
    // 2. Put in the data
    new_node->data = new_data;
    // 3. If the linked list is empty, make the new node as head
    if (*head_ref == NULL) {
        new_node->prev = NULL;
        *head_ref = new_node;
        return;
    }
    // 4. If the position is 0, handle it like inserting at the beginning
    if (position == 0) {
        new_node->next = *head_ref;
        new_node->prev = NULL;
        (*head_ref)->prev = new_node;
        *head_ref = new_node;
        return;
    }
    // 5. Else traverse till the position - 1 node
    struct Node* temp = *head_ref;
    for (int i = 0; temp != NULL && i < position - 1; i++) {
        temp = temp->next;
    }
    // 6. If the position is more than the number of nodes, insert at the end
    if (temp == NULL) {
        append(head_ref, new_data);
        return;
    }
    // 7. Adjust the pointers to insert the new node
    new_node->next = temp->next;
    new_node->prev = temp;
    if (temp->next != NULL) {
        temp->next->prev = new_node;
    }
    temp->next = new_node;
}
// Function to print nodes in a given doubly linked list
void printList(struct Node* node) {
    while (node != NULL) {
        printf("%d ", node->data);
        node = node->next;
    }
    printf("\n");
}
int main() {
    struct Node* head = NULL; // Start with an empty list
    append(&head, 1);
    append(&head, 3);
    append(&head, 4);
    insertAtPosition(&head, 2, 1); // Insert 2 at position 1
    printf("Created DLL is: ");
    printList(head); // Output: 1 2 3 4 
    return 0;
}

Output:

1 2 3 4 

Deletion operation

Three cases exist for an element to be added to the list.

  1. Deletion at the beginning of DLL
  2. Deletion at the end of the DLL
  3. Deletion at a specific location in the DLL

Case 1: Deletion at the beginning of the DLL

Deletion at beginning in the doubly linked list
  • The following actions can be taken to remove the first node in a doubly linked list:
    • Verify that the list is empty and that nothing needs to be deleted. Go back.
    • The head pointer should be kept in a variable, like temp.
    • Head = head->next updates the head of the linked list to the node adjacent to the current head.
    • Update head->prev = NULL to reflect the new head’s previous reference to NULL if it is not NULL.

Implementation of the Program in 4 languages using the above approach

class Node:
    def __init__(self, data):
        self.data = data
        self.prev = None
        self.next = None
class DoublyLinkedList:
    def __init__(self):
        self.head = None
    def delete_at_beginning(self):
        """Deletes the node at the beginning of the doubly linked list."""
        # 1. If the list is empty, do nothing
        if self.head is None:
            return
        # 2. If the list has only one node, set head to None
        if self.head.next is None:
            self.head = None
            return
        # 3. Update the head to the next node
        self.head = self.head.next
        # 4. Set the 'prev' pointer of the new head to None
        self.head.prev = None
    def printList(self, node):
        """Prints the data of all nodes in the doubly linked list."""
        while node is not None:
            print(node.data, end=" ")
            last = node
            node = node.next
# Example usage:
dll = DoublyLinkedList()
dll.append(2)
dll.append(4)
dll.append(8)
dll.append(10)
print("Created DLL is: ")
dll.printList(dll.head)  # Output: 2 4 8 10 
dll.delete_at_beginning()
print("\nDLL after deleting the first node: ")
dll.printList(dll.head)  # Output: 4 8 10
#include <iostream>
using namespace std;
// Node structure for a doubly linked list
struct Node {
    int data;
    Node* prev;
    Node* next;
};
class DoublyLinkedList {
public:
    Node* head; // Pointer to the head of the list
    DoublyLinkedList() : head(nullptr) {} // Constructor
    // Function to insert a new node at the end
    void append(int new_data) {
        // 1. Allocate memory for the new node
        Node* new_node = new Node;
        // 2. Put in the data
        new_node->data = new_data;
        // 3. This new node is going to be the last node, so make next of it as NULL
        new_node->next = nullptr;
        // 4. If the Linked List is empty, then make the new node as head
        if (head == nullptr) {
            new_node->prev = nullptr;
            head = new_node;
            return;
        }
        // 5. Else traverse till the last node
        Node* last = head;
        while (last->next != nullptr) {
            last = last->next;
        }
        // 6. Change the next of the last node
        last->next = new_node;
        // 7. Make the last node as previous of the new node
        new_node->prev = last;
    }
    // Function to delete a node at the beginning of the Doubly Linked List
    void deleteAtBeginning() {
        // 1. If the list is empty, do nothing
        if (head == nullptr) {
            return;
        }
        // 2. Store the old head
        Node* temp = head;
        // 3. If the list has only one node, set head to NULL
        if (head->next == nullptr) {
            head = nullptr;
        } else {
            // 4. Move the head pointer to the next node
            head = head->next;
            // 5. Set the 'prev' pointer of the new head to NULL
            head->prev = nullptr;
        }
        // 6. Free the memory occupied by the deleted node
        delete temp;
    }
    // Function to print nodes in a given doubly linked list
    void printList(Node* node) {
        while (node != nullptr) {
            cout << node->data << " ";
            node = node->next;
        }
        cout << endl;
    }
};
// Example usage
int main() {
    DoublyLinkedList dll;
    dll.append(2);
    dll.append(4);
    dll.append(8);
    dll.append(10);
    cout << "Created DLL is: ";
    dll.printList(dll.head); // Output: 2 4 8 10
    dll.deleteAtBeginning();
    cout << "\nDLL after deleting the first node: ";
    dll.printList(dll.head); // Output: 4 8 10
    return 0;
}
class Node {
    int data;
    Node prev;
    Node next;
    // Constructor to create a new node
    Node(int d) { 
        data = d; 
        prev = null; 
        next = null; 
    }
}
class DoublyLinkedList {
    Node head; // Head of the list
    // Function to insert a new node at the end of the Doubly Linked List
    public void append(int new_data) {
        // 1. Allocate the Node & put in the data
        Node new_node = new Node(new_data);
        // 2. This new node is going to be the last node, so make next of it as null
        new_node.next = null;
        // 3. If the Linked List is empty, then make the new node as head
        if (head == null) {
            new_node.prev = null;
            head = new_node;
            return;
        }
        // 4. Else traverse till the last node
        Node last = head;
        while (last.next != null)
            last = last.next;
        // 5. Change the next of the last node
        last.next = new_node;
        // 6. Make last node as previous of new node 
        new_node.prev = last;
    }
    // Function to delete a node at the beginning of the Doubly Linked List
    public void deleteAtBeginning() {
        // 1. If the list is empty, do nothing
        if (head == null) {
            return;
        }
        // 2. If the list has only one node, set head to null
        if (head.next == null) {
            head = null;
            return;
        }
        // 3. Move the head pointer to the next node
        head = head.next;
        // 4. Set the 'prev' pointer of the new head to null
        head.prev = null;
    }
    // Function to print nodes in a given doubly linked list 
    public void printList(Node node) {
        while (node != null) {
            System.out.print(node.data + " ");
            node = node.next;
        }
        System.out.println();
    }
    public static void main(String[] args) {
        DoublyLinkedList dll = new DoublyLinkedList();
        dll.append(2);
        dll.append(4);
        dll.append(8);
        dll.append(10);
        System.out.print("Created DLL is: ");
        dll.printList(dll.head); // Output: 2 4 8 10
        dll.deleteAtBeginning();
        System.out.print("\nDLL after deleting the first node: ");
        dll.printList(dll.head); // Output: 4 8 10
    }
}
#include <stdio.h>
#include <stdlib.h>
// Structure of a node in the Doubly Linked List
struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
};
// Function to insert a new node at the end of the Doubly Linked List
void append(struct Node** head_ref, int new_data) {
    // 1. Allocate memory for the new node
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
    // 2. Put in the data
    new_node->data = new_data;
    // 3. This new node is going to be the last node, so make next of it as NULL
    new_node->next = NULL;
    // 4. If the Linked List is empty, then make the new node as head
    if ((*head_ref) == NULL) {
        new_node->prev = NULL;
        (*head_ref) = new_node;
        return;
    }
    // 5. Else traverse till the last node
    struct Node* last = (*head_ref);
    while (last->next != NULL) {
        last = last->next;
    }
    // 6. Change the next of the last node
    last->next = new_node;
    // 7. Make the last node as previous of the new node
    new_node->prev = last;
}
// Function to delete a node at the beginning of the Doubly Linked List
void deleteAtBeginning(struct Node** head_ref) {
    // 1. If the list is empty, do nothing
    if (*head_ref == NULL) {
        return;
    }
    // 2. Store the old head
    struct Node* temp = *head_ref;
    // 3. If the list has only one node, set head to NULL
    if ((*head_ref)->next == NULL) {
        *head_ref = NULL;
    } else {
        // 4. Move the head pointer to the next node
        *head_ref = (*head_ref)->next;
        // 5. Set the 'prev' pointer of the new head to NULL
        (*head_ref)->prev = NULL;
    }
    // 6. Free the memory occupied by the deleted node
    free(temp);
}
// Function to print nodes in a given doubly linked list
void printList(struct Node* node) {
    while (node != NULL) {
        printf("%d ", node->data);
        node = node->next;
    }
    printf("\n");
}
int main() {
    struct Node* head = NULL; // Start with an empty list
    append(&head, 2);
    append(&head, 4);
    append(&head, 8);
    append(&head, 10);
    printf("Created DLL is: ");
    printList(head); // Output: 2 4 8 10
    deleteAtBeginning(&head);
    printf("\nDLL after deleting the first node: ");
    printList(head); // Output: 4 8 10
    return 0;
}

Output:

Created DLL is: 2 4 8 10
DLL after deleting the first node: 4 8 10

Case 2: Deletion at the end of the DLL

Deletion at end in the doubly linked list
  • In a doubly linked list, we may use the following procedures to remove the last node:
    • Verify that the doubly linked list has no entries. There is nothing to remove if it is empty.
    • Proceed to the last node of the doubly linked list, say curr if the list is not empty.
    • curr->prev->next = NULL, update the next pointer of the secondto-last node to NULL.
    • Release the memory used for the removed node.

Implementation of the Program in 4 languages using the above approach

class Node:
    def __init__(self, data):
        self.data = data
        self.prev = None
        self.next = None
class DoublyLinkedList:
    def __init__(self):
        self.head = None
    def append(self, new_data):
        """Inserts a new node with 'new_data' at the end of the doubly linked list."""
        new_node = Node(new_data)
        if self.head is None:
            self.head = new_node
            return
        last = self.head
        while last.next:
            last = last.next
        last.next = new_node
        new_node.prev = last
    def delete_at_end(self):
        """Deletes the node at the end of the doubly linked list."""
        # 1. If the list is empty, do nothing
        if self.head is None:
            return
        # 2. If the list has only one node, set head to None
        if self.head.next is None:
            self.head = None
            return
        # 3. Traverse to the last node
        temp = self.head
        while temp.next:
            temp = temp.next
        # 4. Set the 'next' pointer of the second-to-last node to None
        temp.prev.next = None
        # 5. Delete the last node (temp)
        del temp
    def printList(self, node):
        """Prints the data of all nodes in the doubly linked list."""
        while node:
            print(node.data, end=" ")
            last = node
            node = node.next
# Example usage:
dll = DoublyLinkedList()
dll.append(2)
dll.append(4)
dll.append(8)
dll.append(10)
print("Created DLL is: ")
dll.printList(dll.head)  # Output: 2 4 8 10
dll.delete_at_end()
print("\nDLL after deleting the last node: ")
dll.printList(dll.head)  # Output: 2 4 8 
#include <iostream>
using namespace std;
// Node structure for a doubly linked list
struct Node {
    int data;
    Node* prev;
    Node* next;
};
class DoublyLinkedList {
public:
    Node* head; // Pointer to the head of the list
    DoublyLinkedList() : head(nullptr) {} // Constructor
    // Function to insert a new node at the end
    void append(int new_data) {
        // 1. Allocate memory for the new node
        Node* new_node = new Node;
        // 2. Put in the data
        new_node->data = new_data;
        // 3. This new node is going to be the last node, so make next of it as NULL
        new_node->next = nullptr;
        // 4. If the Linked List is empty, then make the new node as head
        if (head == nullptr) {
            new_node->prev = nullptr;
            head = new_node;
            return;
        }
        // 5. Else traverse till the last node
        Node* last = head;
        while (last->next != nullptr) {
            last = last->next;
        }
        // 6. Change the next of the last node
        last->next = new_node;
        // 7. Make the last node as previous of the new node
        new_node->prev = last;
    }
    // Function to delete the node at the end of the Doubly Linked List
    void deleteAtEnd() {
        // 1. If the list is empty, do nothing
        if (head == nullptr) {
            return;
        }
        // 2. If the list has only one node, set head to NULL
        if (head->next == nullptr) {
            delete head; 
            head = nullptr;
            return;
        }
        // 3. Traverse to the last node
        Node* temp = head;
        while (temp->next != nullptr) {
            temp = temp->next;
        }
        // 4. Set the 'next' pointer of the second-to-last node to NULL
        temp->prev->next = nullptr;
        // 5. Delete the last node
        delete temp; 
    }
    // Function to print nodes in a given doubly linked list
    void printList(Node* node) {
        while (node != nullptr) {
            cout << node->data << " ";
            node = node->next;
        }
        cout << endl;
    }
};
// Example usage
int main() {
    DoublyLinkedList dll;
    dll.append(2);
    dll.append(4);
    dll.append(8);
    dll.append(10);
    cout << "Created DLL is: ";
    dll.printList(dll.head); // Output: 2 4 8 10
    dll.deleteAtEnd();
    cout << "\nDLL after deleting the last node: ";
    dll.printList(dll.head); // Output: 2 4 8
    return 0;
}
class Node {
    int data;
    Node prev;
    Node next;
    // Constructor to create a new node
    Node(int d) { 
        data = d; 
        prev = null; 
        next = null; 
    }
}
class DoublyLinkedList {
    Node head; // Head of the list
    // Function to insert a new node at the end of the Doubly Linked List
    public void append(int new_data) {
        // 1. Allocate the Node & put in the data
        Node new_node = new Node(new_data);
        // 2. This new node is going to be the last node, so make next of it as null
        new_node.next = null;
        // 3. If the Linked List is empty, then make the new node as head
        if (head == null) {
            new_node.prev = null;
            head = new_node;
            return;
        }
        // 4. Else traverse till the last node
        Node last = head;
        while (last.next != null)
            last = last.next;
        // 5. Change the next of the last node
        last.next = new_node;
        // 6. Make last node as previous of new node 
        new_node.prev = last;
    }
    // Function to delete a node at the end of the Doubly Linked List
    public void deleteAtEnd() {
        // 1. If the list is empty, do nothing
        if (head == null) {
            return;
        }
        // 2. If the list has only one node, set head to null
        if (head.next == null) {
            head = null;
            return;
        }
        // 3. Traverse to the last node
        Node temp = head;
        while (temp.next != null) {
            temp = temp.next;
        }
        // 4. Set the 'next' pointer of the second to last node to null
        temp.prev.next = null;
    }
    // Function to print nodes in a given doubly linked list 
    public void printList(Node node) {
        while (node != null) {
            System.out.print(node.data + " ");
            node = node.next;
        }
        System.out.println();
    }
    public static void main(String[] args) {
        DoublyLinkedList dll = new DoublyLinkedList();
        dll.append(2);
        dll.append(4);
        dll.append(8);
        dll.append(10);
        System.out.print("Created DLL is: ");
        dll.printList(dll.head); // Output: 2 4 8 10
        dll.deleteAtEnd();
        System.out.print("\nDLL after deleting the last node: ");
        dll.printList(dll.head); // Output: 2 4 8 
    }
}
#include <stdio.h>
#include <stdlib.h>
// Structure of a node in the Doubly Linked List
struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
};
// Function to insert a new node at the end of the Doubly Linked List
void append(struct Node** head_ref, int new_data) {
    // 1. Allocate memory for the new node
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
    // 2. Put in the data
    new_node->data = new_data;
    // 3. This new node is going to be the last node, so make next of it as NULL
    new_node->next = NULL;
    // 4. If the Linked List is empty, then make the new node as head
    if ((*head_ref) == NULL) {
        new_node->prev = NULL;
        (*head_ref) = new_node;
        return;
    }
    // 5. Else traverse till the last node
    struct Node* last = (*head_ref);
    while (last->next != NULL) {
        last = last->next;
    }
    // 6. Change the next of the last node
    last->next = new_node;
    // 7. Make the last node as previous of the new node
    new_node->prev = last;
}
// Function to delete a node at the end of the Doubly Linked List
void deleteAtEnd(struct Node** head_ref) {
    // 1. If the list is empty, do nothing
    if (*head_ref == NULL) {
        return;
    }
    // 2. If the list has only one node, set head to NULL
    if ((*head_ref)->next == NULL) {
        free(*head_ref);
        *head_ref = NULL;
        return;
    }
    // 3. Traverse to the last node
    struct Node* temp = *head_ref;
    while (temp->next != NULL) {
        temp = temp->next;
    }
    // 4. Set the 'next' pointer of the second-to-last node to NULL
    temp->prev->next = NULL;
    // 5. Free the memory occupied by the deleted node
    free(temp);
}
// Function to print nodes in a given doubly linked list
void printList(struct Node* node) {
    while (node != NULL) {
        printf("%d ", node->data);
        node = node->next;
    }
    printf("\n");
}
int main() {
    struct Node* head = NULL; // Start with an empty list
    append(&head, 2);
    append(&head, 4);
    append(&head, 8);
    append(&head, 10);
    printf("Created DLL is: ");
    printList(head); // Output: 2 4 8 10
    deleteAtEnd(&head);
    printf("\nDLL after deleting the last node: ");
    printList(head); // Output: 2 4 8
    return 0;
}

Output:

Created DLL is: 
2 4 8 10 
DLL after deleting the last node: 
2 4 8

Case 3: Deletion at a specific location of the DLL

Deletion at specific location in the doubly linked list
  • The following procedures can be used to remove a node from a doubly linked list at a certain position:
    • Say, curr when you approach the node at the designated location.
    • Modify the pointers to bypass the node that has to be destroyed if the location is valid.
    • For non-head nodes, the next pointer of the predecessor node should be modified to point to the successor node: curr->prev->next = curr->next.
    • Curr->next->prev = curr->prev is the new pointer from the node after curr to the node before curr if curr is not the last node in the linked list.
    • Release the memory used by the node that was removed.

Implementation of the Program in 4 languages using the above approach

class Node:
    def __init__(self, data):
        self.data = data
        self.prev = None
        self.next = None
class DoublyLinkedList:
    def __init__(self):
        self.head = None
    def append(self, new_data):
        """Inserts a new node at the end of the doubly linked list."""
        new_node = Node(new_data)
        if self.head is None:
            self.head = new_node
            return
        last = self.head
        while last.next:
            last = last.next
        last.next = new_node
        new_node.prev = last
    def delete_at_position(self, position):
        """Deletes the node at the specified 'position' in the doubly linked list."""
        # 1. If the list is empty, do nothing
        if self.head is None:
            return
        # 2. If the position is 0, delete the head node
        if position == 0:
            # If only one node, set head to None
            if self.head.next is None:
                self.head = None
                return
            # Update head to the next node and set its 'prev' to None
            self.head = self.head.next
            self.head.prev = None
            return
        # 3. Traverse to the node at the given position
        temp = self.head
        count = 0
        while temp is not None and count < position:
            temp = temp.next
            count += 1
        # 4. If the position is beyond the list length, do nothing
        if temp is None:
            return
        # 5. If the node to be deleted is not the last node
        if temp.next is not None:
            temp.next.prev = temp.prev
        # 6. If the node to be deleted is not the first node
        if temp.prev is not None:
            temp.prev.next = temp.next
        # 7. Delete the node
        del temp
    def printList(self, node):
        """Prints the data of all nodes in the doubly linked list."""
        while node:
            print(node.data, end=" ")
            node = node.next
# Example usage:
dll = DoublyLinkedList()
dll.append(2)
dll.append(4)
dll.append(8)
dll.append(10)
print("Created DLL is: ")
dll.printList(dll.head)  # Output: 2 4 8 10
dll.delete_at_position(2) # Delete node at position 2
print("\nDLL after deleting at position 2: ")
dll.printList(dll.head)  # Output: 2 4 10
#include <iostream>
using namespace std;
// Node structure for a doubly linked list
struct Node {
    int data;
    Node* prev;
    Node* next;
};
class DoublyLinkedList {
public:
    Node* head; // Pointer to the head of the list
    DoublyLinkedList() : head(nullptr) {} // Constructor
    // Function to insert a new node at the end
    void append(int new_data) {
        // 1. Allocate memory for the new node
        Node* new_node = new Node;
        // 2. Put in the data
        new_node->data = new_data;
        // 3. This new node is going to be the last node, so make next of it as NULL
        new_node->next = nullptr;
        // 4. If the Linked List is empty, then make the new node as head
        if (head == nullptr) {
            new_node->prev = nullptr;
            head = new_node;
            return;
        }
        // 5. Else traverse till the last node
        Node* last = head;
        while (last->next != nullptr) {
            last = last->next;
        }
        // 6. Change the next of the last node
        last->next = new_node;
        // 7. Make the last node as previous of the new node
        new_node->prev = last;
    }
    // Function to delete a node at a given position
    void deleteAtPosition(int position) {
        // 1. If the list is empty, do nothing
        if (head == nullptr) {
            return;
        }
        // 2. If the position is 0, delete the head node
        if (position == 0) {
            Node* temp = head;
            head = head->next;
            if (head != nullptr) {
                head->prev = nullptr;
            }
            delete temp;
            return;
        }
        // 3. Traverse to the node at the given position
        Node* temp = head;
        for (int i = 0; temp != nullptr && i < position; i++) {
            temp = temp->next;
        }
        // 4. If the position is more than the number of nodes, do nothing
        if (temp == nullptr) {
            return;
        }
        // 5. If the node to be deleted is not the last node
        if (temp->next != nullptr) {
            temp->next->prev = temp->prev;
        }
        // 6. If the node to be deleted is not the first node
        if (temp->prev != nullptr) {
            temp->prev->next = temp->next;
        }
        // 7. Delete the node
        delete temp;
    }
    // Function to print nodes in a given doubly linked list
    void printList(Node* node) {
        while (node != nullptr) {
            cout << node->data << " ";
            node = node->next;
        }
        cout << endl;
    }
};
// Example usage
int main() {
    DoublyLinkedList dll;
    dll.append(2);
    dll.append(4);
    dll.append(8);
    dll.append(10);
    cout << "Created DLL is: ";
    dll.printList(dll.head); // Output: 2 4 8 10
    dll.deleteAtPosition(2); // Delete node at position 2
    cout << "\nDLL after deleting at position 2: ";
    dll.printList(dll.head); // Output: 2 4 10
    return 0;
}
class Node {
    int data;
    Node prev;
    Node next;
    // Constructor to create a new node
    Node(int d) { 
        data = d; 
        prev = null; 
        next = null; 
    }
}
class DoublyLinkedList {
    Node head; // Head of the list
    // Function to insert a new node at the end of the Doubly Linked List
    public void append(int new_data) {
        // 1. Allocate the Node & put in the data
        Node new_node = new Node(new_data);
        // 2. This new node is going to be the last node, so make next of it as null
        new_node.next = null;
        // 3. If the Linked List is empty, then make the new node as head
        if (head == null) {
            new_node.prev = null;
            head = new_node;
            return;
        }
        // 4. Else traverse till the last node
        Node last = head;
        while (last.next != null)
            last = last.next;
        // 5. Change the next of the last node
        last.next = new_node;
        // 6. Make last node as previous of new node 
        new_node.prev = last;
    }
    // Function to delete a node at a given position
    public void deleteAtPosition(int position) {
        // 1. If the list is empty, do nothing
        if (head == null) {
            return;
        }
        // 2. If the position is 0, delete the head node
        if (position == 0) {
            head = head.next;
            if (head != null) {
                head.prev = null;
            }
            return;
        }
        // 3. Traverse to the node at the given position
        Node temp = head;
        for (int i = 0; temp != null && i < position; i++) {
            temp = temp.next;
        }
        // 4. If the position is more than the number of nodes, do nothing
        if (temp == null) {
            return;
        }
        // 5. If the node to be deleted is not the last node
        if (temp.next != null) {
            temp.next.prev = temp.prev;
        }
        // 6. If the node to be deleted is not the first node
        if (temp.prev != null) {
            temp.prev.next = temp.next;
        }
    }
    // Function to print nodes in a given doubly linked list 
    public void printList(Node node) {
        while (node != null) {
            System.out.print(node.data + " ");
            node = node.next;
        }
        System.out.println();
    }
    public static void main(String[] args) {
        DoublyLinkedList dll = new DoublyLinkedList();
        dll.append(2);
        dll.append(4);
        dll.append(8);
        dll.append(10);
        System.out.print("Created DLL is: ");
        dll.printList(dll.head); // Output: 2 4 8 10
        dll.deleteAtPosition(2); // Delete node at position 2
        System.out.print("\nDLL after deleting at position 2: ");
        dll.printList(dll.head); // Output: 2 4 10
    }
}
#include <stdio.h>
#include <stdlib.h>
// Structure of a node in the Doubly Linked List
struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
};
// Function to insert a new node at the end of the Doubly Linked List
void append(struct Node** head_ref, int new_data) {
    // 1. Allocate memory for the new node
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
    // 2. Put in the data
    new_node->data = new_data;
    // 3. This new node is going to be the last node, so make next of it as NULL
    new_node->next = NULL;
    // 4. If the Linked List is empty, then make the new node as head
    if ((*head_ref) == NULL) {
        new_node->prev = NULL;
        (*head_ref) = new_node;
        return;
    }
    // 5. Else traverse till the last node
    struct Node* last = (*head_ref);
    while (last->next != NULL) {
        last = last->next;
    }
    // 6. Change the next of the last node
    last->next = new_node;
    // 7. Make last node as previous of new node 
    new_node->prev = last;
}
// Function to delete a node at a given position
void deleteAtPosition(struct Node** head_ref, int position) {
    // 1. If the list is empty, do nothing
    if (*head_ref == NULL) {
        return;
    }
    // 2. If the position is 0, delete the head node
    if (position == 0) {
        struct Node* temp = *head_ref;
        *head_ref = (*head_ref)->next;
        if (*head_ref != NULL) {
            (*head_ref)->prev = NULL;
        }
        free(temp);
        return;
    }
    // 3. Traverse to the node at the given position
    struct Node* temp = *head_ref;
    for (int i = 0; temp != NULL && i < position; i++) {
        temp = temp->next;
    }
    // 4. If the position is more than the number of nodes, do nothing
    if (temp == NULL) {
        return;
    }
    // 5. If the node to be deleted is not the last node
    if (temp->next != NULL) {
        temp->next->prev = temp->prev;
    }
    // 6. If the node to be deleted is not the first node
    if (temp->prev != NULL) {
        temp->prev->next = temp->next;
    }
    // 7. Free the memory occupied by the deleted node
    free(temp);
}
// Function to print nodes in a given doubly linked list
void printList(struct Node* node) {
    while (node != NULL) {
        printf("%d ", node->data);
        node = node->next;
    }
    printf("\n");
}
int main() {
    struct Node* head = NULL; // Start with an empty list
    append(&head, 2);
    append(&head, 4);
    append(&head, 8);
    append(&head, 10);
    printf("Created DLL is: ");
    printList(head); // Output: 2 4 8 10
    deleteAtPosition(&head, 2); // Delete node at position 2
    printf("\nDLL after deleting at position 2: ");
    printList(head); // Output: 2 4 10
    return 0;
}

Output:

Created DLL is: 
2 4 8 10 
DLL after deleting at position 2: 
2 4 10

Complexity Analysis of Doubly Linked List Operations

OperationTime Complexity (Average)Time Complexity (Worst)Space Complexity
Insertion
– At BeginningO(1)O(1)O(1)
– At EndO(1)O(1)O(1)
– Before Given NodeO(1)O(1)O(1)
– After Given NodeO(1)O(1)O(1)
Deletion
– At BeginningO(1)O(1)O(1)
– At EndO(1)O(1)O(1)
– At Given PositionO(n)O(n)O(1)
TraversalO(n)O(n)O(1)
SearchO(n)O(n)O(1)
Space Used (Overall)O(n)

1. What is a Doubly Linked List?

  • A doubly linked list is a linear data structure where each node contains data and two pointers: one pointing to the next node and one pointing to the previous node. 
  • Doubly-linked lists offer more versatility in navigation and modification than singly-linked lists due to their bidirectional structure.

2. What are the Advantages of a Doubly Linked List over a Singly Linked List?

  • Doubly linked lists allow for traversal in both directions, making it easier to access elements before a given node. 
  • They also enable more efficient deletion operations, especially when deleting a node given only a reference to that node.

3. What are the Disadvantages of a Doubly Linked List?

  • The primary drawback is the increased memory usage caused by the additional “previous” pointer in each node.
  • This can be a concern if memory usage is critical in your application.

4. What are Some Real-World Applications of Doubly Linked Lists?

Doubly linked lists are used in various applications, including:

  • Navigation History in Browsers: The “back” and “forward” buttons rely on doubly linked lists to efficiently move between visited pages.
  • Undo/Redo Functionality in Software: Storing a history of actions for undo/redo operations can be effectively implemented using a doubly linked list.

5. How Do You Insert and Delete Nodes in a Doubly Linked List?

  • When inserting or deleting nodes in a doubly linked list, it’s crucial to meticulously update the “next” and “previous” pointers of the adjacent nodes.
  • After each operation, it’s important to verify that the list’s connections are correct.
Scroll to Top