Doubly Linked List Tutorial - GeeksforGeeks (2024)

Last Updated : 11 Jun, 2024

Improve

A doubly linked list is a more complex data structure than a singly linked list, but it offers several advantages. The main advantage of a doubly linked list is that it allows for efficient traversal of the list in both directions. This is because each node in the list contains a pointer to the previous node and a pointer to the next node. This allows for quick and easy insertion and deletion of nodes from the list, as well as efficient traversal of the list in both directions.

Doubly Linked List Tutorial - GeeksforGeeks (1)

Doubly Linked List in Data Structure

What is a Doubly Linked List?

A doubly linked list is a data structure that consists of a set of nodes, each of which contains a value and two pointers, one pointing to the previous node in the list and one pointing to the next node in the list. This allows for efficient traversal of the list in both directions, making it suitable for applications where frequent insertions and deletions are required.

Representation of Doubly Linked List in Data Structure:

In a data structure, a doubly linked list is represented using nodes that have three fields:

  1. Data
  2. A pointer to the next node (next)
  3. A pointer to the previous node (prev).

Node Definition:

Here is how a node in a Doubly Linked List is typically represented:

C++
struct Node { // To store the Value or data. int data; // Pointer to point the Previous Element Node* prev; // Pointer to point the Next Element Node* next;};

Each node in a Doubly Linked List contains the data it holds, a pointer to the next node in the list, and a pointer to the previous node in the list. By linking these nodes together through the next and prev pointers, we can traverse the list in both directions (forward and backward), which is a key feature of a Doubly Linked List.

Operations on Doubly Linked List:

  • Traversal in Doubly Linked List
  • Searching in Doubly Linked List
  • Finding Length of Doubly Linked List
  • Insertion in Doubly Linked List:
    • Insertion at the beginning of Doubly Linked List
    • Insertion at the end of the Doubly Linked List
    • Insertion at a specific position in Doubly Linked List
  • Deletion in Doubly Linked List:
    • Deletion of a node at the beginning of Doubly Linked List
    • Deletion of a node at the end of Doubly Linked List
    • Deletion of a node at a specific position in Doubly Linked List

Let’s go through each of the operations mentioned above, one by one.

Traversal in Doubly Linked List:

To Traverse the doubly list, we can use the following steps:

a. Forward Traversal:

  • Initialize a pointer to the head of the linked list.
  • While the pointer is not null:
  • Visit the data at the current node.
  • Move the pointer to the next node.

b. Backward Traversal:

  • Initialize a pointer to the tail of the linked list.
  • While the pointer is not null:
  • Visit the data at the current node.
  • Move the pointer to the previous node.

Below are the implementation of the above approach:

C++
#include <iostream>using namespace std;// Define the Node structurestruct Node { int data; // Data stored in the node Node* next; // Pointer to the next node in the list Node* prev; // Pointer to the previous node in the list // Constructor to initialize Node with data Node(int data) : data(data), next(nullptr), prev(nullptr) {}};// Function to traverse the doubly linked list in forward directionvoid forwardTraversal(Node* head) { // Start traversal from the head of the list Node* current = head; // Continue until current node is not null (end of list) while (current != nullptr) { // Output data of the current node cout << current->data << " "; // Move to the next node current = current->next; } // Print newline after traversal cout << endl;}// Function to traverse the doubly linked list in backward directionvoid backwardTraversal(Node* tail) { // Start traversal from the tail of the list Node* current = tail; // Continue until current node is not null (end of list) while (current != nullptr) { // Output data of the current node cout << current->data << " "; // Move to the previous node current = current->prev; } // Print newline after traversal cout << endl;}int main() { // Sample usage of the doubly linked list and traversal functions Node* head = new Node(1); Node* second = new Node(2); Node* third = new Node(3); head->next = second; second->prev = head; second->next = third; third->prev = second; cout << "Forward Traversal:" << endl; forwardTraversal(head); cout << "Backward Traversal:" << endl; backwardTraversal(third); // Free memory allocated for nodes delete head; delete second; delete third; return 0;}
Java
class Node { int data; Node next; Node prev; public Node(int data) { this.data = data; this.next = null; this.prev = null; }}public class DoublyLinkedListTraversal { // Function to traverse the doubly linked list in forward direction static void forwardTraversal(Node head) { // Start traversal from the head of the list Node current = head; // Continue until the current node is not null (end of the list) while (current != null) { // Output data of the current node System.out.print(current.data + " "); // Move to the next node current = current.next; } // Print newline after traversal System.out.println(); } // Function to traverse the doubly linked list in backward direction static void backwardTraversal(Node tail) { // Start traversal from the tail of the list Node current = tail; // Continue until the current node is not null (end of the list) while (current != null) { // Output data of the current node System.out.print(current.data + " "); // Move to the previous node current = current.prev; } // Print newline after traversal System.out.println(); } public static void main(String[] args) { // Sample usage of the doubly linked list and traversal functions Node head = new Node(1); Node second = new Node(2); Node third = new Node(3); head.next = second; second.prev = head; second.next = third; third.prev = second; System.out.println("Forward Traversal:"); forwardTraversal(head); System.out.println("Backward Traversal:"); backwardTraversal(third); }}
Python
class Node: def __init__(self, data): self.data = data self.next = None self.prev = None# Function to traverse the doubly linked list in forward directiondef forward_traversal(head): # Start traversal from the head of the list current = head # Continue until the current node is not None (end of the list) while current is not None: # Output data of the current node print(current.data, end=" ") # Move to the next node current = current.next # Print newline after traversal print()# Function to traverse the doubly linked list in backward directiondef backward_traversal(tail): # Start traversal from the tail of the list current = tail # Continue until the current node is not None (end of the list) while current is not None: # Output data of the current node print(current.data, end=" ") # Move to the previous node current = current.prev # Print newline after traversal print()# Sample usage of the doubly linked list and traversal functionshead = Node(1)second = Node(2)third = Node(3)head.next = secondsecond.prev = headsecond.next = thirdthird.prev = secondprint("Forward Traversal:")forward_traversal(head)print("Backward Traversal:")backward_traversal(third)
JavaScript
class Node { constructor(data) { this.data = data; this.next = null; this.prev = null; }}// Function to traverse the doubly linked list in forward directionfunction forwardTraversal(head) { // Start traversal from the head of the list let current = head; // Continue until the current node is not null (end of the list) while (current !== null) { // Output data of the current node process.stdout.write(current.data + " "); // Move to the next node current = current.next; } // Print newline after traversal console.log();}// Function to traverse the doubly linked list in backward directionfunction backwardTraversal(tail) { // Start traversal from the tail of the list let current = tail; // Continue until the current node is not null (end of the list) while (current !== null) { // Output data of the current node process.stdout.write(current.data + " "); // Move to the previous node current = current.prev; } // Print newline after traversal console.log();}// Sample usage of the doubly linked list and traversal functionslet head = new Node(1);let second = new Node(2);let third = new Node(3);head.next = second;second.prev = head;second.next = third;third.prev = second;console.log("Forward Traversal:");forwardTraversal(head);console.log("Backward Traversal:");backwardTraversal(third);

Output

Forward Traversal:1 2 3 Backward Traversal:3 2 1 

Finding Length of Doubly Linked List:

To find the length of doubly list, we can use the following steps:

  • Start at the head of the list.
  • Traverse through the list, counting each node visited.
  • Return the total count of nodes as the length of the list.

Below are the implementation of the above approach:

C++
// Node structure for doubly linked liststruct Node { int data; // Data stored in the node Node* prev; // Pointer to the previous node Node* next; // Pointer to the next node // Constructor to initialize node with given value Node(int val) : data(val) , prev(nullptr) , next(nullptr) { }};// Function to find the length of a doubly linked listint findLength(Node* head){ // Variable to store the length of the list int length = 0; // Pointer to traverse the list Node* current = head; // Traverse the list until reaching the end while (current != nullptr) { // Increment length for each node visited length++; // Move to the next node current = current->next; } // Return the length of the list return length;}
Java
// Node structure for doubly linked listclass Node { constructor(data) { this.data = data; // Data stored in the node this.prev = null; // Pointer to the previous node this.next = null; // Pointer to the next node }}// Function to find the length of a doubly linked listfunction findLength(head) { let length = 0; // Variable to store the length of the list let current = head; // Pointer to traverse the list // Traverse the list until reaching the end while (current !== null) { length++; // Increment length for each node visited current = current.next; // Move to the next node } return length; // Return the length of the list}
Python
# Node class for doubly linked listclass Node: def __init__(self, val): # Data stored in the node self.data = val # Pointer to the previous node self.prev = None # Pointer to the next node self.next = None# Function to find the length of a doubly linked listdef find_length(head): # Variable to store the length of the list length = 0 # Pointer to traverse the list current = head # Traverse the list until reaching the end while current is not None: # Increment length for each node visited length += 1 # Move to the next node current = current.next # Return the length of the list return length
JavaScript
// Node class for doubly linked listclass Node { constructor(val) { this.data = val; // Data stored in the node this.prev = null; // Pointer to the previous node this.next = null; // Pointer to the next node }}// Function to find the length of a doubly linked listfunction findLength(head) { // Variable to store the length of the list let length = 0; // Pointer to traverse the list let current = head; // Traverse the list until reaching the end while (current !== null) { // Increment length for each node visited length++; // Move to the next node current = current.next; } // Return the length of the list return length;}

Insertion at the Beginning in Doubly Linked List:

Doubly Linked List Tutorial - GeeksforGeeks (2)

Insertion at the Beginning in Doubly Linked List

To insert a new node at the beginning of the doubly list, we can use the following steps:

  • Allocate memory for a new node and assign the provided value to its data field.
  • Set the previous pointer of the new node to nullptr.
  • If the list is empty:
    • Set the next pointer of the new node to nullptr.
    • Update the head pointer to point to the new node.
  • If the list is not empty:
    • Set the next pointer of the new node to the current head.
    • Update the previous pointer of the current head to point to the new node.
    • Update the head pointer to point to the new node.

Below are the implementation of the above approach:

C++
// Define the structure for a node in the doubly linked liststruct Node { int data; // Data stored in the node Node* next; // Pointer to the next node Node* prev; // Pointer to the previous node};// Function to insert a node at the beginning of the listvoid insertBeginning(Node*& head, int value) { // Create a new node Node* newNode = new Node; // Assign the value to the new node newNode->data = value; // Since it's the first node, the previous pointer is nullptr newNode->prev = nullptr; // If the list is empty, make the new node the head if (head == nullptr) { // Since it's the only node, the next pointer is nullptr newNode->next = nullptr; // Update the head pointer to point to the new node head = newNode; } else { // Point the new node's next pointer to the current head newNode->next = head; // Update the previous pointer of the current head to point to the new node head->prev = newNode; // Update the head pointer to point to the new node head = newNode; }}

Insertion at the End of Doubly Linked List

Doubly Linked List Tutorial - GeeksforGeeks (3)

Insertion at the End in Doubly Linked List

To insert a new node at the end of the doubly linked list, we can use the following steps:

  • Allocate memory for a new node and assign the provided value to its data field.
  • Initialize the next pointer of the new node to nullptr.
  • If the list is empty:
    • Set the previous pointer of the new node to nullptr.
    • Update the head pointer to point to the new node.
  • If the list is not empty:
    • Traverse the list starting from the head to reach the last node.
    • Adjust pointers to insert the new node at the end:
      • Set the next pointer of the last node to point to the new node.
      • Set the previous pointer of the new node to point to the last node.’

Below are the implementation of the above approach:

C++
#include <iostream>// Define the structure for a node in the doubly linked liststruct Node { int data; // Data stored in the node Node* next; // Pointer to the next node Node* prev; // Pointer to the previous node};// Function to insert a node at the end of the listvoid insertEnd(Node*& head, int value) { // Create a new node Node* newNode = new Node; // Assign the value to the new node newNode->data = value; // Initialize the next pointer to nullptr newNode->next = nullptr; // Check if the list is empty if (head == nullptr) { // If the list is empty, make the new node the head newNode->prev = nullptr; // Update the head pointer to point to the new node head = newNode; } else { // Start from the head of the list Node* current = head; // Traverse to the end of the list while (current->next != nullptr) { current = current->next; } // Adjust pointers to insert the new node at the end // Set the next pointer of the last node to point to // the new node current->next = newNode; // Set the previous pointer of the new node to point // to the last node newNode->prev = current; }}int main() { // Test the insertEnd function Node* head = nullptr; insertEnd(head, 1); insertEnd(head, 2); insertEnd(head, 3); // Print the list Node* current = head; while (current != nullptr) { std::cout << current->data << " "; current = current->next; } // Delete dynamically allocated memory while (head != nullptr) { Node* temp = head; head = head->next; delete temp; } return 0;}
Java
// Define the structure for a node in the doubly linked listclass Node { int data; // Data stored in the node Node next; // Pointer to the next node Node prev; // Pointer to the previous node  // Constructor to initialize a node with data Node(int data) { this.data = data; this.next = null; this.prev = null; }}// Function to insert a node at the end of the listclass DoublyLinkedList { // Method to insert a node at the end of the list static Node insertEnd(Node head, int value) { // Create a new node Node newNode = new Node(value); // Check if the list is empty if (head == null) { // If the list is empty, make the new node the head head = newNode; } else { // Start from the head of the list Node current = head; // Traverse to the end of the list while (current.next != null) { current = current.next; } // Adjust pointers to insert the new node at the end // Set the next pointer of the last node to point to the new node current.next = newNode; // Set the previous pointer of the new node to point to the last node newNode.prev = current; } return head; }}// Test the insertEnd functionpublic class Main { public static void main(String[] args) { // Initialize an empty list Node head = null; // Insert nodes at the end of the list head = DoublyLinkedList.insertEnd(head, 1); head = DoublyLinkedList.insertEnd(head, 2); head = DoublyLinkedList.insertEnd(head, 3); // Print the list Node current = head; while (current != null) { System.out.println(current.data); current = current.next; } }}
Python
# Define the structure for a node in the doubly linked listclass Node: def __init__(self, data): self.data = data # Data stored in the node self.next = None # Pointer to the next node self.prev = None # Pointer to the previous node# Function to insert a node at the end of the listdef insert_end(head, value): # Create a new node new_node = Node(value) # Check if the list is empty if head is None: # If the list is empty, make the new node the head head = new_node else: # Start from the head of the list current = head # Traverse to the end of the list while current.next is not None: current = current.next # Adjust pointers to insert the new node at the end # Set the next pointer of the last node to point to the new node current.next = new_node # Set the previous pointer of the new node to point to the last node new_node.prev = current return head# Test the insert_end functionhead = Nonehead = insert_end(head, 1)head = insert_end(head, 2)head = insert_end(head, 3)# Print the listcurrent = headwhile current is not None: print(current.data) current = current.next
JavaScript
// Define the structure for a node in the doubly linked listclass Node { constructor(data) { this.data = data; // Data stored in the node this.next = null; // Pointer to the next node this.prev = null; // Pointer to the previous node }}// Function to insert a node at the end of the listfunction insertEnd(head, value) { // Create a new node const newNode = new Node(value); // Check if the list is empty if (head === null) { // If the list is empty, make the new node the head head = newNode; } else { // Start from the head of the list let current = head; // Traverse to the end of the list while (current.next !== null) { current = current.next; } // Adjust pointers to insert the new node at the end // Set the next pointer of the last node to point to the new node current.next = newNode; // Set the previous pointer of the new node to point to the last node newNode.prev = current; } return head;}// Test the insertEnd functionlet head = null;head = insertEnd(head, 1);head = insertEnd(head, 2);head = insertEnd(head, 3);// Print the listlet current = head;while (current !== null) { console.log(current.data); current = current.next;}

Output

1 2 3 

Insertion at a Specific Position of Doubly Linked List

Doubly Linked List Tutorial - GeeksforGeeks (4)

To insert a node at a specific Position in doubly linked list, we can use the following steps:

  • Traverse the list to find the node at the desired position.
  • Create a new node with the data you want to insert.
  • Adjust the pointers of the new node, the previous node, and the next node to include the new node in the list.
  • Update the pointers of the neighboring nodes to maintain the doubly linked list structure.

Below is the implementation of the above approach:

C++
#include <iostream>using namespace std;// Define the structure of a node in the doubly linked liststruct Node { int data; // Data stored in the node Node* prev; // Pointer to the previous node in the list Node* next; // Pointer to the next node in the list};// Function to insert a node at a specific position in the doubly linked listvoid insertAtPosition(Node** head, int position, int data) { // Create a new node and allocate memory Node* newNode = new Node(); // Set the data of the new node newNode->data = data; // Insert at the beginning of the list if (position == 0) { // New node points to the current head newNode->next = *head; // Previous of new node is null as it's the new head newNode->prev = nullptr; if (*head != nullptr) { // If list is not empty, set the previous of old head to new node (*head)->prev = newNode; } // Update the head to point to the new node *head = newNode; } else { // Pointer to traverse the list Node* current = *head; // Counter to track the position int count = 0; // Traverse to the node at position - 1 while (current != nullptr && count < position - 1) { current = current->next; // Move to the next node count++; // Increment position counter } // If reached end of list and position not found if (current == nullptr) { // Inform user about out of range position cout << "Position out of range" << endl; return; // Exit function } // Insert the new node between current and current->next newNode->next = current->next; // New node's next is set to current node's next newNode->prev = current; // New node's previous is set to current node if (current->next != nullptr) { // If there's a node after current, set its previous to new node current->next->prev = newNode; } // Set current node's next to the new node current->next = newNode; }}// Function to print the doubly linked listvoid printList(Node* head) { while (head != nullptr) { cout << head->data << " "; head = head->next; } cout << endl;}// Driver code to test the insertion functionint main() { // Create an empty list Node* head = nullptr; // Insert elements at various positions insertAtPosition(&head, 0, 10); // Insert 10 at position 0 insertAtPosition(&head, 1, 20); // Insert 20 at position 1 insertAtPosition(&head, 2, 30); // Insert 30 at position 2 // Print the list to verify the insertion printList(head); // Expected output: 10 20 30 return 0;}
Java
// Node class represents each node in the doubly linked listclass Node { int data; Node prev; Node next; // Node constructor public Node(int data) { this.data = data; this.prev = null; this.next = null; }}// DoublyLinkedList class represents the entire listclass DoublyLinkedList { Node head; // DoublyLinkedList constructor public DoublyLinkedList() { this.head = null; } // Method to insert a node at a specific position public void insertAtPosition(int position, int data) { Node newNode = new Node(data); if (position == 0) { newNode.next = this.head; newNode.prev = null; if (this.head != null) { this.head.prev = newNode; } this.head = newNode; } else { Node current = this.head; int count = 0; while (current != null && count < position - 1) { current = current.next; count++; } if (current == null) { System.out.println("Position out of range"); return; } newNode.next = current.next; newNode.prev = current; if (current.next != null) { current.next.prev = newNode; } current.next = newNode; } }}// Main classpublic class Main { public static void main(String[] args) { // Create a doubly linked list DoublyLinkedList dll = new DoublyLinkedList(); // Insert nodes at specific positions dll.insertAtPosition(0, 10); dll.insertAtPosition(1, 20); dll.insertAtPosition(2, 30); // Print the list Node current = dll.head; while (current != null) { System.out.print(current.data + " "); current = current.next; } }}
Python
class Node: def __init__(self, data=None): self.data = data self.prev = None self.next = Noneclass DoublyLinkedList: def __init__(self): self.head = None def insertAtPosition(self, position, data): newNode = Node(data) if position == 0: newNode.next = self.head newNode.prev = None if self.head is not None: self.head.prev = newNode self.head = newNode else: current = self.head count = 0 while current is not None and count < position - 1: current = current.next count += 1 if current is None: print("Position out of range") return newNode.next = current.next newNode.prev = current if current.next is not None: current.next.prev = newNode current.next = newNode# Create a doubly linked listdll = DoublyLinkedList()# Insert nodes at specific positionsdll.insertAtPosition(0, 10)dll.insertAtPosition(1, 20)dll.insertAtPosition(2, 30)# Print the listcurrent = dll.headwhile current: print(current.data,end=" ") current = current.next
JavaScript
// Define the structure of a node in the doubly linked listclass Node { constructor(data) { this.data = data; // Data stored in the node this.prev = null; // Pointer to the previous node in the list this.next = null; // Pointer to the next node in the list }}// Function to insert a node at a specific position in the doubly linked listfunction insertAtPosition(head, position, data) { // Create a new node const newNode = new Node(data); // Insert at the beginning of the list if (position === 0) { // New node points to the current head newNode.next = head; // Previous of new node is null as it's the new head newNode.prev = null; if (head !== null) { // If list is not empty, set the previous of old head to new node head.prev = newNode; } // Update the head to point to the new node return newNode; } let current = head; let count = 0; // Traverse to the node at position - 1 while (current !== null && count < position - 1) { current = current.next; count++; } // If reached end of list and position not found if (current === null) { console.log("Position out of range"); return head; // Return the original head unchanged } // Insert the new node between current and current.next newNode.next = current.next; newNode.prev = current; if (current.next !== null) { // If there's a node after current, set its previous to new node current.next.prev = newNode; } // Set current node's next to the new node current.next = newNode; return head;}// Function to print the doubly linked listfunction printList(head) { let current = head; while (current !== null) { console.log(current.data); current = current.next; }}// Driver code to test the insertion function(function main() { // Create an empty list let head = null; // Insert elements at various positions head = insertAtPosition(head, 0, 10); // Insert 10 at position 0 head = insertAtPosition(head, 1, 20); // Insert 20 at position 1 head = insertAtPosition(head, 2, 30); // Insert 30 at position 2 // Print the list to verify the insertion printList(head); // Expected output: 10 20 30})();// This code is contributed by Shivam Gupta

Deletion at the Beginning of doubly linked list

Doubly Linked List Tutorial - GeeksforGeeks (5)

Deletion at the Beginning in Doubly Linked List

To delete a node at the beginning in doubly linked list, we can use the following steps:

  • Check If the list is empty, there is nothing to delete. Return.
  • Check if the node to be deleted is the head node, update the head pointer to point to the next node.
  • If the node to be deleted is not the head node, update the previous pointer of the next node to point to the previous node of the node to be deleted.
  • If the node to be deleted is not the tail node, update the next pointer of the previous node to point to the next node of the node to be deleted.
  • Free the memory allocated to the node to be deleted.

Below is the implementation of the above approach:

C++
// Structure to represent a node in a doubly linked liststruct Node { int data; // Data stored in the node Node* next; // Pointer to the next node in the list Node* prev; // Pointer to the previous node in the list};// Function to delete the node at the beginning of a doubly// linked listvoid deleteAtBeginning(Node** head) { // Check if the list is empty if (*head == nullptr) { return; } // Check if the node to be deleted is the head node if (*head == (*head)->next) { // If the node to be deleted is the head node, // update the head pointer to point to the next node *head = (*head)->next; // If the list has only one node, set the head // pointer to NULL if (*head == nullptr) { return; } // Update the previous pointer of the new head node // to point to NULL (*head)->prev = nullptr;  // Delete the old head node delete *head; return; } // If the node to be deleted is not the head node, // update the previous pointer of the next node to point // to the previous node of the node to be deleted Node* temp = *head; *head = (*head)->next; (*head)->prev = nullptr; // Delete the node to be deleted delete temp;}

Deletion at the End on doubly linked list:

Doubly Linked List Tutorial - GeeksforGeeks (6)

Deletion at a End in Doubly Linked List

To delete a node at the end in doubly linked list, we can use the following steps:

  • Check if the doubly linked list is empty. If it is empty, then there is nothing to delete.
  • If the list is not empty, then move to the last node of the doubly linked list.
  • Update the second-to-last node’s next pointer to NULL, making it the new last node.
  • Free the memory allocated for the node that was deleted.

Below is the implementation of the above approach:

C++
// Structure to represent a node in a doubly linked liststruct Node { int data; // Data stored in the node Node* next; // Pointer to the next node in the list Node* prev; // Pointer to the previous node in the list};void deleteAtEnd(Node*& head) { // Check if the list is empty if (head == nullptr) { return; } // Find the last node Node* curr = head; while (curr->next != nullptr) { curr = curr->next; } // Update the previous node's next pointer Node* prev = nullptr; while (prev->next != curr) { prev = prev->next; } prev->next = nullptr; // Delete the last node delete curr;}
Java
class Node { int data; // Data stored in the node Node next; // Pointer to the next node in the list Node prev; // Pointer to the previous node in the list // Constructor to create a new node Node(int data) { this.data = data; this.next = null; this.prev = null; }}public class DoublyLinkedList { Node head; // Head of the list // Method to delete the node at the end public void deleteAtEnd() { // Check if the list is empty if (head == null) { return; } // Find the last node Node curr = head; while (curr.next != null) { curr = curr.next; } // Update the previous node's next pointer Node prev = curr.prev; if (prev != null) { prev.next = null; } else { // If the list only contains one node head = null; } // Delete the last node (handled by Java's garbage collector) }}
Python
# Structure to represent a node in a doubly linked listclass Node: def __init__(self, data): self.data = data self.next = None self.prev = Nonedef delete_at_end(head): # Check if the list is empty if not head: return # Find the last node curr = head while curr.next: curr = curr.next # Find the node before the last node prev = head while prev.next != curr: prev = prev.next # Update the previous node's next pointer prev.next = None # Delete the last node del curr
JavaScript
class Node { constructor(data) { this.data = data; this.next = null; this.prev = null; }}function deleteAtEnd(head) { // Check if the list is empty if (head === null) { return; } // Find the last node let curr = head; while (curr.next !== null) { curr = curr.next; } // Update the previous node's next pointer let prev = null; let temp = head; while (temp.next !== curr) { prev = temp; temp = temp.next; } if (prev !== null) { prev.next = null; } else { head = null; // If there's only one node } // Delete the last node curr = null;}// This code is contributed by Rambabu

Deletion at a Specific Position in doubly linked list

Doubly Linked List Tutorial - GeeksforGeeks (7)

Deletion at a Specific Position in Doubly Linked List

To delete a node at a specific position in doubly linked list, we can use the following steps:

  • Traverse to the node at the specified position in the doubly linked list.
  • Adjust the pointers to skip the node to be deleted.
  • Update the next pointer of the node before the deleted node to point to the node after the deleted node.
  • Update the previous pointer of the node after the deleted node to point to the node before the deleted node.
  • Free the memory allocated for the deleted node.

Below is the implementation of the above approach:

C++
#include <iostream>struct Node { int data; Node* prev; Node* next;  Node(int val) : data(val), prev(nullptr), next(nullptr) {}};void deleteNodeAtPosition(Node* head, int position) { if (!head) { return; } Node* current = head; for (int i = 1; current && i < position; ++i) { current = current->next; } if (!current) { return; } if (current->prev) { current->prev->next = current->next; } if (current->next) { current->next->prev = current->prev; } if (head == current) { head = current->next; } delete current; // Deallocate memory for the deleted node (C++ specific)}
Java
class Node { int data; // Data stored in the node Node prev; // Reference to the previous node in the doubly linked list Node next; // Reference to the next node in the doubly linked list}void deleteNodeAtPosition(Node head, int position) { // If the list is empty, there is nothing to delete if (head == null) { return; } Node current = head; // Traverse to the node at the specified position for (int i = 1; current != null && i < position; ++i) { current = current.next; } // If the specified position is beyond the end of the list, do nothing if (current == null) { return; } // Adjust references to skip the node to be deleted if (current.prev != null) { // Update the next reference of the previous node current.prev.next = current.next; } if (current.next != null) { // Update the prev reference of the next node current.next.prev = current.prev; } // Update head if the node to be deleted is the head if (head == current) { // Update the head reference if the first node is deleted head = current.next; } // Java's garbage collector will automatically deallocate memory for the deleted node}
Python
class Node: def __init__(self, data=None): self.data = data # Data stored in the node self.prev = None # Reference to the previous node in the doubly linked list self.next = None # Reference to the next node in the doubly linked listdef deleteNodeAtPosition(head, position): # If the list is empty, there is nothing to delete if head is None: return current = head # Traverse to the node at the specified position for i in range(1, position): if current is None: return current = current.next # If the specified position is beyond the end of the list, do nothing if current is None: return # Adjust references to skip the node to be deleted if current.prev is not None: # Update the next reference of the previous node current.prev.next = current.next if current.next is not None: # Update the prev reference of the next node current.next.prev = current.prev # Update head if the node to be deleted is the head if head == current: # Update the head reference if the first node is deleted head = current.next # Python's garbage collector will automatically deallocate memory for the deleted node
JavaScript
class Node { constructor(data) { this.data = data; this.prev = null; this.next = null; }}function deleteNodeAtPosition(head, position) { if (!head) { return; } let current = head; for (let i = 1; current && i < position; ++i) { current = current.next; } if (!current) { return; } if (current.prev) { current.prev.next = current.next; } if (current.next) { current.next.prev = current.prev; } if (head === current) { head = current.next; }}

Advantages of Doubly Linked List

  • Efficient traversal in both directions: Doubly linked lists allow for efficient traversal of the list in both directions, making it suitable for applications where frequent insertions and deletions are required.
  • Easy insertion and deletion of nodes: The presence of pointers to both the previous and next nodes makes it easy to insert or delete nodes from the list, without having to traverse the entire list.
  • Can be used to implement a stack or queue: Doubly linked lists can be used to implement both stacks and queues, which are common data structures used in programming.

Disadvantages of Doubly Linked List

  • More complex than singly linked lists: Doubly linked lists are more complex than singly linked lists, as they require additional pointers for each node.
  • More memory overhead: Doubly linked lists require more memory overhead than singly linked lists, as each node stores two pointers instead of one.

Applications of doubly linked lists:

  • Implementation of undo and redo functionality in text editors.
  • Cache implementation where quick insertion and deletion of elements are required.
  • Browser history management to navigate back and forth between visited pages.
  • Music player applications to manage playlists and navigate through songs efficiently.
  • Implementing data structures like Deque (double-ended queue) for efficient insertion and deletion at both ends.


H

harendrakumar123

Improve

Previous Article

Doubly Linked List meaning in DSA

Next Article

Difference between Singly linked list and Doubly linked list

Please Login to comment...

Doubly Linked List Tutorial - GeeksforGeeks (2024)

References

Top Articles
Latest Posts
Article information

Author: Pres. Lawanda Wiegand

Last Updated:

Views: 6487

Rating: 4 / 5 (71 voted)

Reviews: 86% of readers found this page helpful

Author information

Name: Pres. Lawanda Wiegand

Birthday: 1993-01-10

Address: Suite 391 6963 Ullrich Shore, Bellefort, WI 01350-7893

Phone: +6806610432415

Job: Dynamic Manufacturing Assistant

Hobby: amateur radio, Taekwondo, Wood carving, Parkour, Skateboarding, Running, Rafting

Introduction: My name is Pres. Lawanda Wiegand, I am a inquisitive, helpful, glamorous, cheerful, open, clever, innocent person who loves writing and wants to share my knowledge and understanding with you.