Open In App

Reverse a Doubly Linked List by swapping data

Improve
Improve
Like Article
Like
Save
Share
Report

Given a Doubly Linked List, we are asked to reverse the list in place without using any extra space.

Examples: 

Input : 1 <--> 2 <--> 5 <--> 6 <--> 7
Output : 7 <--> 6 <--> 5 <--> 2 <--> 1

Input : 11 <--> 22 <--> 33 <--> 22 <--> 1
Output : 1 <--> 22 <--> 33 <--> 22 <--> 11 

We have discussed three methods to reverse a doubly-linked list: Reverse a doubly-linked list, Reverse a Doubly Linked List (Set 2) and Reverse a Doubly linked list using recursion.
The first two methods work in O(n) time and require no extra space. The first method works by swapping the next and previous pointers of each node. The second method takes each node from the list and adds it to the beginning of the list.
There is another approach that is a bit more intuitive, but also a bit more costly. 
This method is similar to the reverse array. To reverse an array, we put two pointers-one at the beginning and another at the end of the list. We then swap the data of the two pointers and advance both pointers toward each other. We stop either when the two pointers meet or when they cross each other. We perform exactly n/2 swaps, and the time complexity is also O(N).
A doubly linked list has both a previous and a next pointer, which means we can traverse in both forward and backward directions in the list. So if we put a pointer( say left pointer) at the beginning of the list and another right pointer at the end of the list, we can move these pointers toward each other by advancing the left pointer and receding the right pointer.

Algorithm:

Step 1: Set LEFT to head of list
Step 2: Traverse the list and set RIGHT to end of the list 
Step 3: Repeat following steps while LEFT != RIGHT and 
        LEFT->PREV != RIGHT
Step 4: Swap LEFT->DATA and RIGHT->DATA
Step 5: Advance LEFT pointer by one, LEFT = LEFT->NEXT
Step 6: Recede RIGHT pointer by one, i.e RIGHT = RIGHT->PREV
        [END OF LOOP]
Step 7: End

A Note on the comparative efficiency of the three methods 

A few things must be mentioned. This method is simple to implement, but it is also more costly when compared to the pointer-exchange method. This is because we swap data and not pointers. Swapping data can be more costly if the nodes are large complex data types with multiple data members. In contrast, the pointer to the node will always be a simpler data type and either 4 or 8 bytes.

Below is the implementation of the algorithm. 

C++




// Cpp Program to Reverse a List using Data Swapping
 
#include <bits/stdc++.h>
using namespace std;
 
struct Node {
    int data;
    struct Node *prev, *next;
};
 
Node* newNode(int val)
{
    Node* temp = new Node;
    temp->data = val;
    temp->prev = temp->next = nullptr;
    return temp;
}
 
void printList(Node* head)
{
    while (head->next != nullptr) {
        cout << head->data << " <--> ";
        head = head->next;
    }
    cout << head->data << endl;
}
 
// Insert a new node at the head of the list
void insert(Node** head, int val)
{
    Node* temp = newNode(val);
    temp->next = *head;
    (*head)->prev = temp;
    (*head) = temp;
}
 
// Function to reverse the list
void reverseList(Node** head)
{
    Node* left = *head, * right = *head;
 
    // Traverse the list and set right pointer to
    // end of list
    while (right->next != nullptr)
        right = right->next;
 
    // Swap data of left and right pointer and move
    // them towards each other until they meet or
    // cross each other
    while (left != right && left->prev != right) {
 
        // Swap data of left and right pointer
        swap(left->data, right->data);
 
        // Advance left pointer
        left = left->next;
 
        // Advance right pointer
        right = right->prev;
    }
}
 
// Driver code
int main()
{
    Node* head = newNode(5);
    insert(&head, 4);
    insert(&head, 3);
    insert(&head, 2);
    insert(&head, 1);
 
    printList(head);
    cout << "List After Reversing" << endl;
    reverseList(&head);
    printList(head);
 
    return 0;
}


C




// C Program to Reverse a List using Data Swapping
#include <stdio.h>
#include <stdlib.h>
 
struct Node {
  int data;
  struct Node* prev;
  struct Node* next;
};
 
// Insert a new node at the head of the list
void insert(struct Node** head, int val)
{
  struct Node* temp;
  temp = (struct Node*)malloc(sizeof(struct Node));
  temp->data = val;
  temp->next = *head;
  temp->prev = NULL;
  if ((*head) != NULL) {
    (*head)->prev = temp;
  }
  (*head) = temp;
}
 
void printList(struct Node* head)
{
  struct Node* temp = head;
  while (temp->next != NULL) {
    printf("%d <--> ", temp->data);
    temp = temp->next;
  }
  printf("%d\n", temp->data);
}
 
// Function to reverse the list
void reverseList(struct Node* head)
{
  struct Node* left = head;
  struct Node* right = head;
 
  // Traverse the list and set right pointer to
  // end of list
  while (right->next != NULL) {
    right = right->next;
  }
 
  // Swap data of left and right pointer and move
  // them towards each other until they meet or
  // cross each other
  while (left != right && left->prev != right) {
 
    // Swap data of left and right pointer
    int temp = left->data;
    left->data = right->data;
    right->data = temp;
 
    // Advance left pointer
    left = left->next;
 
    // Advance right pointer
    right = right->prev;
  }
}
 
int main()
{
 
  // code
  struct Node* head = NULL;
  insert(&head, 5);
  insert(&head, 4);
  insert(&head, 3);
  insert(&head, 2);
  insert(&head, 1);
 
  printList(head);
  printf("List After Reversing\n");
 
  reverseList(head);
  printList(head);
 
  return 0;
 
  // This code is contributed by lokesh (lokeshmvs21)
}


Java




// Java Program to Reverse a List using Data Swapping
import java.util.*;
import java.io.*;
 
class GFG
{
static class Node
{
    int data;
    Node prev, next;
};
 
static Node newNode(int val)
{
    Node temp = new Node();
    temp.data = val;
    temp.prev = temp.next = null;
    return temp;
}
 
static void printList(Node head)
{
    while (head.next != null)
    {
        System.out.print(head.data+ " <--> ");
        head = head.next;
    }
    System.out.println( head.data );
}
 
// Insert a new node at the head of the list
static Node insert(Node head, int val)
{
    Node temp = newNode(val);
    temp.next = head;
    (head).prev = temp;
    (head) = temp;
    return head;
}
 
// Function to reverse the list
static Node reverseList(Node head)
{
    Node left = head, right = head;
 
    // Traverse the list and set right pointer to
    // end of list
    while (right.next != null)
        right = right.next;
 
    // Swap data of left and right pointer and move
    // them towards each other until they meet or
    // cross each other
    while (left != right && left.prev != right)
    {
 
        // Swap data of left and right pointer
        int t = left.data;
        left.data = right.data;
        right.data = t;
 
        // Advance left pointer
        left = left.next;
 
        // Advance right pointer
        right = right.prev;
    }
    return head;
}
 
// Driver code
public static void main(String args[])
{
    Node head = newNode(5);
    head = insert(head, 4);
    head = insert(head, 3);
    head = insert(head, 2);
    head = insert(head, 1);
 
    printList(head);
    System.out.println("List After Reversing");
    head=reverseList(head);
    printList(head);
 
}
}
 
// This code is contributed by Arnab Kundu


Python3




# Python3 Program to Reverse a List
# using Data Swapping
import math
 
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None
 
def newNode(val):
    temp = Node(val)
    temp.data = val
    temp.prev =None
    temp.next = None
    return temp
 
def printList( head):
    while (head.next != None):
        print(head.data, end = "<-->")
        head = head.next
     
    print(head.data)
 
# Insert a new node at the head of the list
def insert(head, val):
    temp = newNode(val)
    temp.next = head
    (head).prev = temp
    (head) = temp
    return head
 
# Function to reverse the list
def reverseList( head):
    left = head
    right = head
 
    # Traverse the list and set right
    # pointer to end of list
    while (right.next != None):
        right = right.next
 
    # Swap data of left and right pointer
    # and move them towards each other
    # until they meet or cross each other
    while (left != right and left.prev != right):
 
        # Swap data of left and right pointer
        t = left.data
        left.data = right.data
        right.data = t
         
        # Advance left pointer
        left = left.next
 
        # Advance right pointer
        right = right.prev
     
    return head
 
# Driver code
if __name__=='__main__':
 
    head = newNode(5)
    head = insert(head, 4)
    head = insert(head, 3)
    head = insert(head, 2)
    head = insert(head, 1)
 
    printList(head)
    print("List After Reversing")
    head = reverseList(head)
    printList(head)
 
# This code is contributed by AbhiThakur


C#




// C# Program to Reverse a List using Data Swapping
using System;
 
class GFG
{
 
    public class Node
    {
        public int data;
        public Node prev, next;
    };
     
    static Node newNode(int val)
    {
        Node temp = new Node();
        temp.data = val;
        temp.prev = temp.next = null;
        return temp;
    }
     
    static void printList(Node head)
    {
        while (head.next != null)
        {
            Console.Write(head.data+ " <--> ");
            head = head.next;
        }
        Console.WriteLine( head.data );
    }
     
    // Insert a new node at the head of the list
    static Node insert(Node head, int val)
    {
        Node temp = newNode(val);
        temp.next = head;
        (head).prev = temp;
        (head) = temp;
        return head;
    }
     
    // Function to reverse the list
    static Node reverseList(Node head)
    {
        Node left = head, right = head;
     
        // Traverse the list and set right pointer to
        // end of list
        while (right.next != null)
            right = right.next;
     
        // Swap data of left and right pointer and move
        // them towards each other until they meet or
        // cross each other
        while (left != right && left.prev != right)
        {
     
            // Swap data of left and right pointer
            int t = left.data;
            left.data = right.data;
            right.data = t;
     
            // Advance left pointer
            left = left.next;
     
            // Advance right pointer
            right = right.prev;
        }
        return head;
    }
     
    // Driver code
    public static void Main(String []args)
    {
        Node head = newNode(5);
        head = insert(head, 4);
        head = insert(head, 3);
        head = insert(head, 2);
        head = insert(head, 1);
     
        printList(head);
        Console.WriteLine("List After Reversing");
        head=reverseList(head);
        printList(head);
     
    }
}
 
// This code has been contributed by 29AjayKumar


Javascript




<script>
    // javascript Program to Reverse a List using Data Swapping
 
    class Node {
        constructor(val) {
            this.data = val;
            this.prev = null;
            this.next = null;
        }
    }
 
    function newNode(val) {
        var temp = new Node();
        temp.data = val;
        temp.prev = temp.next = null;
        return temp;
    }
 
    function printList(head) {
        while (head.next != null) {
            document.write(head.data + " <-> ");
            head = head.next;
        }
        document.write(head.data);
    }
 
    // Insert a new node at the head of the list
    function insert(head , val) {
        var temp = newNode(val);
        temp.next = head;
        (head).prev = temp;
        (head) = temp;
        return head;
    }
 
    // Function to reverse the list
    function reverseList(head) {
        var left = head, right = head;
 
        // Traverse the list and set right pointer to
        // end of list
        while (right.next != null)
            right = right.next;
 
        // Swap data of left and right pointer and move
        // them towards each other until they meet or
        // cross each other
        while (left != right && left.prev != right) {
 
            // Swap data of left and right pointer
            var t = left.data;
            left.data = right.data;
            right.data = t;
 
            // Advance left pointer
            left = left.next;
 
            // Advance right pointer
            right = right.prev;
        }
        return head;
    }
 
    // Driver code
     
    var head = newNode(5);
    head = insert(head, 4);
    head = insert(head, 3);
    head = insert(head, 2);
    head = insert(head, 1);
 
    printList(head);
    document.write("<br/>List After Reversing<br/>");
    head = reverseList(head);
    printList(head);
 
 
// This code contributed by umadevi9616
</script>


Output

1 <--> 2 <--> 3 <--> 4 <--> 5
List After Reversing
5 <--> 4 <--> 3 <--> 2 <--> 1

Time Complexity: O(n), as we are using a loop to traverse n times. Where n is the number of nodes in the linked list.
Auxiliary Space: O(1), as we are not using any extra space.



Last Updated : 16 Dec, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads