Open In App

Reverse a Doubly Linked List

Last Updated : 28 Aug, 2024
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Share
Report
News Follow

Given a Doubly Linked List, the task is to reverse the Doubly Linked List.

Examples:

Input: Doubly Linked List = 1 <-> 2 <-> 3 -> NULL 

Insertion-at-the-End-in-Doubly-Linked-List2

Doubly Linked List

Output: Reversed Doubly Linked List = 3 <-> 2 <-> 1 -> NULL

Insertion-at-the-End-in-Doubly-Linked-List1

Reversed Doubly Linked List

Input: Doubly Linked List = 1 ->NULL 
Output: Reversed Doubly Linked List = 1 ->NULL 

[Naive Approach] Using RecursionO(n) Time and O(n) Space

The idea is to use recursion to reverse the links in the doubly linked list. The recursive function will traverse the list and reverse the links while backtracking.

Step-by-Step algorithm:

  • Recursively traverse the doubly linked list until it reaches the last node.
  • While backtracking, reverse the links between the nodes. To reverse the links:
    • Change the next pointer of the current node to point to its previous node.
    • Change the prev pointer of the current node to point to its next node.
  • Adjust the head of the doubly linked list to point to the last node.

Below is the implementation of the above approach:

C++
// C++ program to reverse a
//doubly linked list using recursion

#include <iostream>
using namespace std;

class Node {
public:
    int data;
    Node *next, *prev;

    Node(int val) {
        data = val;
        next = nullptr;
        prev = nullptr;
    }
};

// Recursive function to reverse a doubly linked list
Node *reverse(Node *curr) { 
  
    // Base case: if the list is empty or we
      // reach the end of the list
    if (curr == NULL)
        return NULL;

    // Swap the next and prev pointers
    Node *temp = curr->prev;
    curr->prev = curr->next;
    curr->next = temp;

    // If the previous node (after swap) is null,
      // this is the new head
    if (curr->prev == nullptr)
        return curr;

    // Recurse for the next node
    return reverse(curr->prev);
}

void printList(Node *node) {
    while (node != nullptr) {
        cout << node->data << " ";
        node = node->next;
    }
}

int main() {
  
    // Create a hard-coded doubly linked list:
    // 1 <-> 2 <-> 3 <-> 4
    Node *head = new Node(1);
    head->next = new Node(2);
    head->next->prev = head;
    head->next->next = new Node(3);
    head->next->next->prev = head->next;
    head->next->next->next = new Node(4);
    head->next->next->next->prev = head->next->next;

    cout << "Original Linked list" << endl;
    printList(head);
    head = reverse(head);
    cout << "\nReversed Linked list" << endl;
    printList(head);

    return 0;
}
C
// C program to reverse a doubly
//linked list using recursion

#include <stdio.h>
struct Node {
    int data;
    struct Node *next;
    struct Node *prev;
};

// Recursive function to reverse a doubly linked list 
struct Node *reverse(struct Node *curr) {
  
    // Base case: If the list is empty or we
      // reach the end of the list
    if (curr == NULL) return NULL;

    // Swap the next and prev pointers
    struct Node *temp = curr->prev;
    curr->prev = curr->next;
    curr->next = temp;

    // If the previous node (after swap) is NULL
      // his is the new head
    if (curr->prev == NULL) return curr;

    // Recurse for the next node 
    return reverse(curr->prev);
}

void printList(struct Node *node) {
    while (node != NULL) {
        printf("%d ", node->data);
        node = node->next;
    }
    printf("\n");
}

struct Node *createNode(int new_data) { 
    struct Node *new_node = 
      (struct Node *)malloc(sizeof(struct Node));
    new_node->data = new_data;
    new_node->next = NULL;
    new_node->prev = NULL;
    return new_node;
}

int main() {
  
    // Create a hrad-coded doubly linked list:
    // 1 <-> 2 <-> 3 <-> 4
    struct Node *head = createNode(1);
    head->next = createNode(2);
    head->next->prev = head;
    head->next->next = createNode(3);
    head->next->next->prev = head->next;
    head->next->next->next = createNode(4);
    head->next->next->next->prev = head->next->next;

    printf("Original Linked list\n");
    printList(head);
    head = reverse(head);
    printf("Reversed Linked list\n");
    printList(head);

    return 0;
}
Java
// Java program to reverse a
// doubly linked list using recursion

class GfG {
    static Node head;

    static class Node {
        int data;
        Node next, prev;

        Node(int d) {
            data = d;
            next = prev = null;
        }
    }

    // Recursive function to reverse a doubly linked list
    static Node reverse(Node curr) {
      
        // Base case: If list is empty or we 
          // reach the end of the list
        if (curr == null)
            return null;

        // Swap the next and prev pointers
        Node temp = curr.prev;
        curr.prev = curr.next;
        curr.next = temp;

        // If prev is null after swap, this is the new head
        if (curr.prev == null) {
            return curr;
        }

        // Recurse for the next node
        return reverse(curr.prev);
    }

    static void printList(Node node) {
        while (node != null) {
            System.out.print(node.data + " ");
            node = node.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
      
        // Manually create a doubly linked list:
        // 1 <-> 2 <-> 3 <-> 4
        head = new Node(1);
        head.next = new Node(2);
        head.next.prev = head;
        head.next.next = new Node(3);
        head.next.next.prev = head.next;
        head.next.next.next = new Node(4);
        head.next.next.next.prev = head.next.next;

        System.out.println("Original linked list:");
        printList(head);

        // Reverse the doubly linked list
        head = reverse(head);

        System.out.println("Reversed linked list:");
        printList(head);
    }
}
Python
# Python program to reverse a doubly
# linked list using recursion

class Node:
    def __init__(self, val):
        self.data = val
        self.next = None
        self.prev = None

# Recursive function to reverse a doubly linked list
def reverse(curr):
  
    # Base case: if the list is empty or we reach the end of the list
    if curr is None:
        return None

    # Swap the next and prev pointers
    temp = curr.prev
    curr.prev = curr.next
    curr.next = temp

    # If the previous node (after swap) is null, this is the new head
    if curr.prev is None:
        return curr

    # Recurse for the next node
    return reverse(curr.prev)

def print_list(node):
    while node is not None:
        print(node.data, end=" ")
        node = node.next
    print()

if __name__ == "__main__":
  
    # Create a hard-coded doubly linked list:
    # 1 <-> 2 <-> 3 <-> 4
    head = Node(1)
    head.next = Node(2)
    head.next.prev = head
    head.next.next = Node(3)
    head.next.next.prev = head.next
    head.next.next.next = Node(4)
    head.next.next.next.prev = head.next.next

    print("Original Linked list")
    print_list(head)
    head = reverse(head)
    print("\nReversed Linked list")
    print_list(head)
C#
// C# program to reverse a doubly
// linked list using recursion

using System;

public class Node {
    public int Data;
    public Node Next;
    public Node Prev;

    public Node(int val) {
        Data = val;
        Next = null;
        Prev = null;
    }
}

class GfG {
      
    // Recursive function to reverse a doubly linked list
    static Node Reverse(Node curr) {
          
        // Base case: if the list is empty or we reach the
          // end of the list
        if (curr == null)
            return null;

        // Swap the next and prev pointers
        Node temp = curr.Prev;
        curr.Prev = curr.Next;
        curr.Next = temp;

        // If the previous node (after swap) is null, 
          // this is the new head
        if (curr.Prev == null)
            return curr;

        // Recurse for the next node
        return Reverse(curr.Prev);
    }

    // Function to print the linked list
    static void PrintList(Node node) {
        while (node != null) {
            Console.Write(node.Data + " ");
            node = node.Next;
        }
        Console.WriteLine();
    }

    static void Main() {
          
        // Create a hard-coded doubly linked list:
        // 1 <-> 2 <-> 3 <-> 4
        Node head = new Node(1);
        head.Next = new Node(2);
        head.Next.Prev = head;
        head.Next.Next = new Node(3);
        head.Next.Next.Prev = head.Next;
        head.Next.Next.Next = new Node(4);
        head.Next.Next.Next.Prev = head.Next.Next;

        Console.WriteLine("Original Linked list");
        PrintList(head);
        
        head = Reverse(head);
        
        Console.WriteLine("Reversed Linked list");
        PrintList(head);
    }
}
JavaScript
// Javascript program to reverse a doubly
// linked list using recursion

class Node {
    constructor(val) {
        this.data = val;
        this.next = null;
        this.prev = null;
    }
}

// Recursive function to reverse a doubly linked list
function reverse(curr) {
    // Base case: if the list is empty or we reach the end of the list
    if (curr === null) {
        return null;
    }

    // Swap the next and prev pointers
    const temp = curr.prev;
    curr.prev = curr.next;
    curr.next = temp;

    // If the previous node (after swap) is null, this is the new head
    if (curr.prev === null) {
        return curr;
    }

    // Recurse for the next node
    return reverse(curr.prev);
}

// Function to print the linked list
function printList(node) {
    let output = '';
    while (node !== null) {
        output += node.data + ' ';
        node = node.next;
    }
    console.log(output.trim());
}

// Create a hard-coded doubly linked list:
// 1 <-> 2 <-> 3 <-> 4
const head = new Node(1);
head.next = new Node(2);
head.next.prev = head;
head.next.next = new Node(3);
head.next.next.prev = head.next;
head.next.next.next = new Node(4);
head.next.next.next.prev = head.next.next;

console.log("Original Linked list:");
printList(head);

const reversedHead = reverse(head);

console.log("\nReversed Linked list:");
printList(reversedHead);

Output
Original Linked list
1 2 3 4 
Reversed Linked list
4 3 2 1 

Time Complexity: O(n), where n are the number of nodes in doubly linked list.
Auxiliary Space: O(n)

[Expected Approach] Using Two Pointers – O(n) Time and O(1) Space

The idea is to reverse doubly linked list using two pointers for traversing through the list and swapping the next and previous pointers of every two consecutive nodes.

Step-by-step algorithm:

  • Initially, prevNode is set to NULL and currNode starts at the head.
  • As the list is traversed,
    • Update prevNode to currNode’s prev, prevNode = currNode->prev.
    • Update currNode’s prev pointer to its next node, currNode->prev = currNode->next.
    • Update currNode’s next pointer to prevNode, currNode->next = prevNode.
    • Move currNode to the next node, currNode = currNode->prev.
  • After traversing all the nodes, prevNode will point to the second node of the reversed list, so update the previous pointer of prevNode as the new head of the linked list, head = prevNode->prev and return it.

Working of the above algorithm:


Below is the implementation of the above approach:

C++
// C++ code to Reverse a doubly linked list,
// using two pointers
#include <iostream>
using namespace std;
class Node {
  public:
    int data;
    Node *next;
    Node *prev;
    Node(int new_data) {
        data = new_data;
        next = NULL;
        prev = NULL;
    }
};

// Function to reverse a doubly linked list
Node *reverse(Node *head) {

    // If the list is empty or has only one node,
      // return the head as is
    if (head == nullptr || head->next == nullptr)
        return head;

    Node *prevNode = NULL;
    Node *currNode = head;

    // Traverse the list and reverse the links
    while (currNode != nullptr) {
      
          // Swap the next and prev pointers
        prevNode = currNode->prev;
        currNode->prev = currNode->next;

        currNode->next = prevNode;
      
          // Move to the next node in the original list 
          // (which is now previous due to reversal)
        currNode = currNode->prev;
    }

    // The final node in the original list
    // becomes the new head after reversal
    return prevNode->prev;
}
void printList(Node *node) {
    while (node != nullptr) {
        cout << node->data << " ";
        node = node->next;
    }
    cout << endl;
}

int main() {
  
    // Create a doubly linked list: 
      // 1 <-> 2 <-> 3 <-> 4
    Node *head = new Node(1);
    head->next = new Node(2);
    head->next->prev = head;
    head->next->next = new Node(3);
    head->next->next->prev = head->next;
    head->next->next->next = new Node(4);
    head->next->next->next->prev = head->next->next;
    cout << "Original Doubly Linked List" << endl;
    printList(head);
    head = reverse(head);
    cout << "Reversed Doubly Linked List" << endl;
    printList(head);
    return 0;
}
C
// C code to Reverse a doubly linked list,
// using two pointers

#include <stdio.h>
struct Node {
    int data;
    struct Node *next;
    struct Node *prev;
};

// Function to reverse a Doubly Linked List using two pointers
struct Node *reverse(struct Node *head) {
    if (head == NULL || head->next == NULL)
        return head;

    struct Node *prevNode = NULL;
    struct Node *currNode = head;

    // Traverse the list and reverse the links
    while (currNode != NULL) {
      
        // Swap the next and prev pointers
        prevNode = currNode->prev;
        currNode->prev = currNode->next;
        currNode->next = prevNode;

        // Move to the next node in the original list 
          // (which is now previous due to reversal)
        currNode = currNode->prev;
    }

    // The final node processed will be the new head
    // Fix head pointer
    if (prevNode != NULL)
        head = prevNode->prev;

    return head;
}

void printList(struct Node *node) {
    while (node != NULL) {
        printf("%d ", node->data);
        node = node->next;
    }
    printf("\n");
}

struct Node *createNode(int new_data){
    struct Node *new_node = 
      (struct Node *)malloc(sizeof(struct Node));
    new_node->data = new_data;
    new_node->next = NULL;
    new_node->prev = NULL;
    return new_node;
}

int main() {
  
    // Create a hard-coded doubly linked list: 
      // 1 <-> 2 <-> 3 <-> 4
    struct Node *head = createNode(1);
    head->next = createNode(2);
    head->next->prev = head;
    head->next->next = createNode(3);
    head->next->next->prev = head->next;
    head->next->next->next = createNode(4);
    head->next->next->next->prev = head->next->next;

    printf("Original Doubly Linked List\n");
    printList(head);

    head = reverse(head);

    printf("Reversed Doubly Linked List\n");
    printList(head);

    return 0;
}
Java
// Java code to Reverse a doubly linked list,
// using two pointers
class Node {
    int data;
    Node next;
    Node prev;

    Node(int data) {
        this.data = data;
        this.next = null;
        this.prev = null;
    }
}

public class GfG {

    // Function to reverse a Doubly Linked List using two
    // pointers
    static Node reverse(Node head) {
        if (head == null || head.next == null) {
            return head;
        }

        Node currNode = head;
        Node prevNode = null;

        // Traverse the list and reverse the links
        while (currNode != null) {
          
            // Swap the next and prev pointers
            prevNode = currNode.prev;
            currNode.prev = currNode.next;
            currNode.next = prevNode;

            // Move to the next node in the original list
            // (which is now previous due to reversal)
            currNode = currNode.prev;
        }

        // Update head of Doubly Linked List
        head = prevNode.prev;

        return head;
    }

    static void printList(Node node) {
        while (node != null) {
            System.out.print(node.data + " ");
            node = node.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
      
        // Create a doubly linked list:
          // 1 <-> 2 <-> 3 <-> 4
        Node head = new Node(1);
        head.next = new Node(2);
        head.next.prev = head;
        head.next.next = new Node(3);
        head.next.next.prev = head.next;
        head.next.next.next = new Node(4);
        head.next.next.next.prev = head.next.next;

        System.out.println("Original Doubly Linked List");
        printList(head);

        head = reverse(head);

        System.out.println("Reversed Doubly Linked List");
        printList(head);
    }
}
Python
# Python code to Reverse a doubly linked list,
# using two pointers
class Node:
    def __init__(self, new_data):
        self.data = new_data
        self.next = None
        self.prev = None

def reverse(head):
      
    # If the list is empty or has only one node,
    # return the head as is
    if head is None or head.next is None:
        return head

    prevNode = None
    currNode = head

    # Traverse the list and reverse the links
    while currNode is not None:
        # Swap the next and prev pointers
        prevNode = currNode.prev
        currNode.prev = currNode.next
        currNode.next = prevNode
        
        # Move to the next node in the original list
        # (which is now previous due to reversal)
        currNode = currNode.prev

    # The final node in the original list
    # becomes the new head after reversal
    return prevNode.prev

def printList(node):
    while node is not None:
        print(node.data, end=" ")
        node = node.next
    print()

if __name__ == "__main__":
      
    # Create a doubly linked list:
    # 1 <-> 2 <-> 3 <-> 4
    head = Node(1)
    head.next = Node(2)
    head.next.prev = head
    head.next.next = Node(3)
    head.next.next.prev = head.next
    head.next.next.next = Node(4)
    head.next.next.next.prev = head.next.next

    print("Original Doubly Linked List")
    printList(head)
    head = reverse(head)
    print("Reversed Doubly Linked List")
    printList(head)
C#
// C# code to Reverse a doubly linked list,
// using two pointers
using System;

class Node {
    public int Data;
    public Node Next;
    public Node Prev;

    public Node(int newData) {
        Data = newData;
        Next = null;
        Prev = null;
    }
}

class GfG {
  
    // Function to reverse a doubly linked list
    static Node Reverse(Node head) {
      
        // If the list is empty or has only one node,
        // return the head as is
        if (head == null || head.Next == null)
            return head;

        Node prevNode = null;
        Node currNode = head;

        // Traverse the list and reverse the links
        while (currNode != null) {
              
            // Swap the next and prev pointers
            prevNode = currNode.Prev;
            currNode.Prev = currNode.Next;
            currNode.Next = prevNode;

            // Move to the next node in the original list
            // (which is now previous due to reversal)
            currNode = currNode.Prev;
        }

        // The final node in the original list
        // becomes the new head after reversal
        return prevNode.Prev;
    }

    static void PrintList(Node node) {
        while (node != null) {
            Console.Write(node.Data + " ");
            node = node.Next;
        }
        Console.WriteLine();
    }

    public static void Main() {
      
        // Create a doubly linked list: 
        // 1 <-> 2 <-> 3 <-> 4
        Node head = new Node(1);
        head.Next = new Node(2);
        head.Next.Prev = head;
        head.Next.Next = new Node(3);
        head.Next.Next.Prev = head.Next;
        head.Next.Next.Next = new Node(4);
        head.Next.Next.Next.Prev = head.Next.Next;

        Console.WriteLine("Original Doubly Linked List");
        PrintList(head);

        head = Reverse(head);

        Console.WriteLine("Reversed Doubly Linked List");
        PrintList(head);
    }
}
JavaScript
// Javascript code to Reverse a doubly linked list,
// using two pointers
class Node {
    constructor(new_data) {
        this.data = new_data;
        this.next = null;
        this.prev = null;
    }
}

// Function to reverse a doubly linked list
function reverse(head) {
    
    // If the list is empty or has only one node,
    // return the head as is
    if (head === null || head.next === null)
        return head;

    let prevNode = null;
    let currNode = head;

    // Traverse the list and reverse the links
    while (currNode !== null) {
        
        // Swap the next and prev pointers
        prevNode = currNode.prev;
        currNode.prev = currNode.next;
        currNode.next = prevNode;

        // Move to the next node in the original list 
        // (which is now previous due to reversal)
        currNode = currNode.prev;
    }

    // The final node in the original list
    // becomes the new head after reversal
    return prevNode.prev;
}

function printList(node) {
    let output = "";
    while (node !== null) {
        output += node.data + " ";
        node = node.next;
    }
    console.log(output);
}


// Create a doubly linked list:
// 1 <-> 2 <-> 3 <-> 4
let head = new Node(1);
head.next = new Node(2);
head.next.prev = head;
head.next.next = new Node(3);
head.next.next.prev = head.next;
head.next.next.next = new Node(4);
head.next.next.next.prev = head.next.next;

console.log("Original Doubly Linked List");
printList(head);

head = reverse(head);

console.log("Reversed Doubly Linked List");
printList(head);

Output
Original Doubly Linked List
1 2 3 4 
Reversed Doubly Linked List
4 3 2 1 

Time Complexity: O(n), where n denotes the number of nodes in the doubly linked list.
Auxiliary Space: O(1)



Next Article
Practice Tags :

Similar Reads

three90RightbarBannerImg
  翻译: