Skip to content
Related Articles

Related Articles

Improve Article

Reverse a doubly linked list in groups of given size

  • Difficulty Level : Medium
  • Last Updated : 09 Aug, 2021
Geek Week

Given a doubly linked list containing n nodes. The problem is to reverse every group of k nodes in the list.
 

Examples: 
 

Prerequisite: Reverse a doubly linked list | Set-2.
Approach: Create a recursive function say reverse(head, k). This function receives the head or the first node of each group of k nodes. It reverses those group of k nodes by applying the approach discussed in Reverse a doubly linked list | Set-2. After reversing the group of k nodes the function checks whether next group of nodes exists in the list or not. If group exists then it makes a recursive call to itself with the first node of the next group and makes the necessary adjustments with the next and previous links of that group. Finally it returns the new head node of the reversed group. 

C++




// C++ implementation to reverse a doubly linked list
// in groups of given size
#include <bits/stdc++.h>
  
using namespace std;
  
// a node of the doubly linked list
struct Node {
    int data;
    Node *next, *prev;
};
  
// function to get a new node
Node* getNode(int data)
{
    // allocate space
    Node* new_node = (Node*)malloc(sizeof(Node));
  
    // put in the data
    new_node->data = data;
    new_node->next = new_node->prev = NULL;
    return new_node;
}
  
// function to insert a node at the beginging
// of the Doubly Linked List
void push(Node** head_ref, Node* new_node)
{
    // since we are adding at the beginning,
    // prev is always NULL
    new_node->prev = NULL;
  
    // link the old list off the new node
    new_node->next = (*head_ref);
  
    // change prev of head node to new node
    if ((*head_ref) != NULL)
        (*head_ref)->prev = new_node;
  
    // move the head to point to the new node
    (*head_ref) = new_node;
}
 
// function to reverse a doubly linked list
// in groups of given size
Node* revListInGroupOfGivenSize(Node* head, int k)
{
    Node *current = head;
    Node* next = NULL;
    Node* newHead = NULL;
    int count = 0;
     
    // reversing the current group of k
    // or less than k nodes by adding
    // them at the beginning of list
    // 'newHead'
    while (current != NULL && count < k)
    {
        next = current->next;
        push(&newHead, current);
        current = next;
        count++;
    }
     
    // if next group exists then making the desired
    // adjustments in the link
    if (next != NULL)
    {
        head->next = revListInGroupOfGivenSize(next, k);
        head->next->prev = head;
    }
     
    // pointer to the new head of the
    // reversed group
    return newHead;
}
 
// Function to print nodes in a
// given doubly linked list
void printList(Node* head)
{
    while (head != NULL) {
        cout << head->data << " ";
        head = head->next;
    }
}
  
// Driver program to test above
int main()
{
    // Start with the empty list
    Node* head = NULL;
  
    // Create doubly linked: 10<->8<->4<->2
    push(&head, getNode(2));
    push(&head, getNode(4));
    push(&head, getNode(8));
    push(&head, getNode(10));
     
    int k = 2;
  
    cout << "Original list: ";
    printList(head);
  
    // Reverse doubly linked list in groups of
    // size 'k'
    head = revListInGroupOfGivenSize(head, k);
  
    cout << "\nModified list: ";
    printList(head);
  
    return 0;
}

Java




// Java implementation to reverse a doubly linked list
// in groups of given size
import java.io.*;
import java.util.*;
 
// Represents a node of doubly linked list
class Node
{
    int data;
    Node next, prev;
}
 
class GFG
{
 
    // function to get a new node
    static Node getNode(int data)
    {
        // allocating node
        Node new_node = new Node();
        new_node.data = data;
        new_node.next = new_node.prev = null;
 
        return new_node;
    }
 
    // function to insert a node at the beginning
    // of the Doubly Linked List
    static Node push(Node head, Node new_node)
    {
        // since we are adding at the beginning,
        // prev is always NULL
        new_node.prev = null;
 
        // link the old list off the new node
        new_node.next = head;
 
        // change prev of head node to new node
        if (head != null)
            head.prev = new_node;
 
        // move the head to point to the new node
        head = new_node;
        return head;
    }
 
    // function to reverse a doubly linked list
    // in groups of given size
    static Node revListInGroupOfGivenSize(Node head, int k)
    {
        Node current = head;
        Node next = null;
        Node newHead = null;
        int count = 0;
 
        // reversing the current group of k
        // or less than k nodes by adding
        // them at the beginning of list
        // 'newHead'
        while (current != null && count < k)
        {
            next = current.next;
            newHead = push(newHead, current);
            current = next;
            count++;
        }
 
        // if next group exists then making the desired
        // adjustments in the link
        if (next != null)
        {
            head.next = revListInGroupOfGivenSize(next, k);
            head.next.prev = head;
        }
 
        // pointer to the new head of the
        // reversed group
        return newHead;
    }
 
    // Function to print nodes in a
    // given doubly linked list
    static void printList(Node head)
    {
        while (head != null)
        {
            System.out.print(head.data + " ");
            head = head.next;
        }
    }
 
    // Driver code
    public static void main(String args[])
    {
        // Start with the empty list
        Node head = null;
             
        // Create doubly linked: 10<->8<->4<->2
        head = push(head, getNode(2));
        head = push(head, getNode(4));
        head = push(head, getNode(8));
        head = push(head, getNode(10));
 
        int k = 2;
             
        System.out.print("Original list: ");
        printList(head);
 
        // Reverse doubly linked list in groups of
        // size 'k'
        head = revListInGroupOfGivenSize(head, k);
 
        System.out.print("\nModified list: ");
        printList(head);
    }
}
 
// This code is contributed by rachana soma

Python




# Python implementation to reverse a doubly linked list
# in groups of given size
 
# Link list node
class Node:
     
    def __init__(self, data):
        self.data = data
        self.next = next
         
# function to get a new node
def getNode(data):
 
    # allocate space
    new_node = Node(0)
 
    # put in the data
    new_node.data = data
    new_node.next = new_node.prev = None
    return new_node
 
# function to insert a node at the beginging
# of the Doubly Linked List
def push(head_ref, new_node):
 
    # since we are adding at the beginning,
    # prev is always None
    new_node.prev = None
 
    # link the old list off the new node
    new_node.next = (head_ref)
 
    # change prev of head node to new node
    if ((head_ref) != None):
        (head_ref).prev = new_node
 
    # move the head to point to the new node
    (head_ref) = new_node
    return head_ref
 
# function to reverse a doubly linked list
# in groups of given size
def revListInGroupOfGivenSize( head, k):
 
    current = head
    next = None
    newHead = None
    count = 0
     
    # reversing the current group of k
    # or less than k nodes by adding
    # them at the beginning of list
    # 'newHead'
    while (current != None and count < k):
     
        next = current.next
        newHead = push(newHead, current)
        current = next
        count = count + 1
     
    # if next group exists then making the desired
    # adjustments in the link
    if (next != None):
     
        head.next = revListInGroupOfGivenSize(next, k)
        head.next.prev = head
     
    # pointer to the new head of the
    # reversed group
    return newHead
 
# Function to print nodes in a
# given doubly linked list
def printList(head):
 
    while (head != None):
        print( head.data , end=" ")
        head = head.next
     
# Driver program to test above
 
# Start with the empty list
head = None
 
# Create doubly linked: 10<.8<.4<.2
head = push(head, getNode(2))
head = push(head, getNode(4))
head = push(head, getNode(8))
head = push(head, getNode(10))
     
k = 2
 
print("Original list: ")
printList(head)
 
# Reverse doubly linked list in groups of
# size 'k'
head = revListInGroupOfGivenSize(head, k)
 
print("\nModified list: ")
printList(head)
 
# This code is contributed by Arnab Kundu

C#




// C# implementation to reverse a doubly linked list
// in groups of given size
using System;
 
// Represents a node of doubly linked list
public class Node
{
    public int data;
    public Node next, prev;
}
 
class GFG
{
 
    // function to get a new node
    static Node getNode(int data)
    {
        // allocating node
        Node new_node = new Node();
        new_node.data = data;
        new_node.next = new_node.prev = null;
 
        return new_node;
    }
 
    // function to insert a node at the beginning
    // of the Doubly Linked List
    static Node push(Node head, Node new_node)
    {
        // since we are adding at the beginning,
        // prev is always NULL
        new_node.prev = null;
 
        // link the old list off the new node
        new_node.next = head;
 
        // change prev of head node to new node
        if (head != null)
            head.prev = new_node;
 
        // move the head to point to the new node
        head = new_node;
        return head;
    }
 
    // function to reverse a doubly linked list
    // in groups of given size
    static Node revListInGroupOfGivenSize(Node head, int k)
    {
        Node current = head;
        Node next = null;
        Node newHead = null;
        int count = 0;
 
        // reversing the current group of k
        // or less than k nodes by adding
        // them at the beginning of list
        // 'newHead'
        while (current != null && count < k)
        {
            next = current.next;
            newHead = push(newHead, current);
            current = next;
            count++;
        }
 
        // if next group exists then making the desired
        // adjustments in the link
        if (next != null)
        {
            head.next = revListInGroupOfGivenSize(next, k);
            head.next.prev = head;
        }
 
        // pointer to the new head of the
        // reversed group
        return newHead;
    }
 
    // Function to print nodes in a
    // given doubly linked list
    static void printList(Node head)
    {
        while (head != null)
        {
            Console.Write(head.data + " ");
            head = head.next;
        }
    }
 
    // Driver code
    public static void Main(String []args)
    {
        // Start with the empty list
        Node head = null;
             
        // Create doubly linked: 10<->8<->4<->2
        head = push(head, getNode(2));
        head = push(head, getNode(4));
        head = push(head, getNode(8));
        head = push(head, getNode(10));
 
        int k = 2;
             
        Console.Write("Original list: ");
        printList(head);
 
        // Reverse doubly linked list in groups of
        // size 'k'
        head = revListInGroupOfGivenSize(head, k);
 
        Console.Write("\nModified list: ");
        printList(head);
    }
}
 
// This code is contributed by Arnab Kundu

Javascript




<script>
// javascript implementation to reverse a doubly linked list
// in groups of given size
// Represents a node of doubly linked list
class Node {
    constructor() {
        this.data = 0;
        this.prev = null;
        this.next = null;
    }
}
    // function to get a new node
    function getNode(data) {
        // allocating node
var new_node = new Node();
        new_node.data = data;
        new_node.next = new_node.prev = null;
 
        return new_node;
    }
 
    // function to insert a node at the beginning
    // of the Doubly Linked List
    function push(head,  new_node) {
        // since we are adding at the beginning,
        // prev is always NULL
        new_node.prev = null;
 
        // link the old list off the new node
        new_node.next = head;
 
        // change prev of head node to new node
        if (head != null)
            head.prev = new_node;
 
        // move the head to povar to the new node
        head = new_node;
        return head;
    }
 
    // function to reverse a doubly linked list
    // in groups of given size
    function revListInGroupOfGivenSize(head , k) {
var current = head;
var next = null;
var newHead = null;
        var count = 0;
 
        // reversing the current group of k
        // or less than k nodes by adding
        // them at the beginning of list
        // 'newHead'
        while (current != null && count < k) {
            next = current.next;
            newHead = push(newHead, current);
            current = next;
            count++;
        }
 
        // if next group exists then making the desired
        // adjustments in the link
        if (next != null) {
            head.next = revListInGroupOfGivenSize(next, k);
            head.next.prev = head;
        }
 
        // pointer to the new head of the
        // reversed group
        return newHead;
    }
 
    // Function to prvar nodes in a
    // given doubly linked list
    function printList(head) {
        while (head != null) {
            document.write(head.data + " ");
            head = head.next;
        }
    }
 
    // Driver code
     
        // Start with the empty list
var head = null;
 
        // Create doubly linked: 10<->8<->4<->2
        head = push(head, getNode(2));
        head = push(head, getNode(4));
        head = push(head, getNode(8));
        head = push(head, getNode(10));
 
        var k = 2;
 
        document.write("Original list: ");
        printList(head);
 
        // Reverse doubly linked list in groups of
        // size 'k'
        head = revListInGroupOfGivenSize(head, k);
 
        document.write("<br/>Modified list: ");
        printList(head);
 
// This code contributed by aashish1995
</script>
Output



Original list: 10 8 4 2 
Modified list: 8 10 2 4 

Time Complexity: O(n).
 

We can further simplify the implementation of this algorithm using the same idea with recursion in just one function.

C++




#include <iostream>
using namespace std;
struct Node {
    int data;
    Node *next, *prev;
};
// function to add Node at the end of a Doubly LinkedList
Node* insertAtEnd(Node* head, int data)
{
 
    Node* new_node = new Node();
    new_node->data = data;
    new_node->next = NULL;
    Node* temp = head;
    if (head == NULL) {
        new_node->prev = NULL;
        head = new_node;
        return head;
    }
 
    while (temp->next != NULL) {
        temp = temp->next;
    }
    temp->next = new_node;
    new_node->prev = temp;
    return head;
}
// function to print Doubly LinkedList
void printDLL(Node* head)
{
    while (head != NULL) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << endl;
}
// function to Reverse a doubly linked list
// in groups of given size
Node* reverseByN(Node* head, int k)
{
    if (!head)
        return NULL;
    head->prev = NULL;
    Node *temp, *curr = head, *newHead;
    int count = 0;
    while (curr != NULL && count < k) {
        newHead = curr;
        temp = curr->prev;
        curr->prev = curr->next;
        curr->next = temp;
        curr = curr->prev;
        count++;
    }
    // checking if the reversed LinkedList size is
    // equal to K or not
    // if it is not equal to k that means we have reversed
    // the last set of size K and we don't need to call the
    // recursive function
    if (count >= k) {
        Node* rest = reverseByN(curr, k);
        head->next = rest;
        if (rest != NULL)
            // it is required for prev link otherwise u wont
            // be backtrack list due to broken links
            rest->prev = head;
    }
    return newHead;
}
int main()
{
    Node* head;
    for (int i = 1; i <= 10; i++) {
        head = insertAtEnd(head, i);
    }
    printDLL(head);
    int n = 4;
    head = reverseByN(head, n);
    printDLL(head);
}

Java




import java.io.*;
 
class Node {
    int data;
    Node next, prev;
}
 
class GFG {
 
    // Function to add Node at the end of a
    // Doubly LinkedList
    static Node insertAtEnd(Node head, int data)
    {
        Node new_node = new Node();
        new_node.data = data;
        new_node.next = null;
        Node temp = head;
 
        if (head == null) {
            new_node.prev = null;
            head = new_node;
            return head;
        }
 
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = new_node;
        new_node.prev = temp;
        return head;
    }
 
    // Function to print Doubly LinkedList
    static void printDLL(Node head)
    {
        while (head != null) {
            System.out.print(head.data + " ");
            head = head.next;
        }
        System.out.println();
    }
 
    // Function to Reverse a doubly linked list
    // in groups of given size
    static Node reverseByN(Node head, int k)
    {
        if (head == null)
            return null;
 
        head.prev = null;
        Node temp;
        Node curr = head;
        Node newHead = null;
        int count = 0;
 
        while (curr != null && count < k) {
            newHead = curr;
            temp = curr.prev;
            curr.prev = curr.next;
            curr.next = temp;
            curr = curr.prev;
            count++;
        }
 
        // Checking if the reversed LinkedList size is
        // equal to K or not. If it is not equal to k
        // that means we have reversed the last set of
        // size K and we don't need to call the
        // recursive function
        if (count >= k) {
            Node rest = reverseByN(curr, k);
            head.next = rest;
            if (rest != null)
                // it is required for prev link otherwise u
                // wont be backtrack list due to broken
                // links
                rest.prev = head;
        }
        return newHead;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        Node head = null;
        for (int i = 1; i <= 10; i++) {
            head = insertAtEnd(head, i);
        }
 
        printDLL(head);
        int n = 4;
 
        head = reverseByN(head, n);
        printDLL(head);
    }
}
 
// This code is contributed by avanitrachhadiya2155

Javascript




<script>
 
class Node {
     
    constructor()
    {
        this.data = 0;
        this.next = null;
        this.prev = null;
    }
};
// function to add Node at the end of a Doubly LinkedList
function insertAtEnd(head, data)
{
 
    var new_node = new Node();
    new_node.data = data;
    new_node.next = null;
    var temp = head;
    if (head == null) {
        new_node.prev = null;
        head = new_node;
        return head;
    }
 
    while (temp.next != null) {
        temp = temp.next;
    }
    temp.next = new_node;
    new_node.prev = temp;
    return head;
}
// function to print Doubly LinkedList
function printDLL(head)
{
    while (head != null) {
        document.write( head.data + " ");
        head = head.next;
    }
    document.write("<br>");
}
// function to Reverse a doubly linked list
// in groups of given size
function reverseByN(head, k)
{
    if (!head)
        return null;
    head.prev = null;
    var temp, curr = head, newHead;
    var count = 0;
    while (curr != null && count < k) {
        newHead = curr;
        temp = curr.prev;
        curr.prev = curr.next;
        curr.next = temp;
        curr = curr.prev;
        count++;
    }
    // checking if the reversed LinkedList size is
    // equal to K or not
    // if it is not equal to k that means we have reversed
    // the last set of size K and we don't need to call the
    // recursive function
    if (count >= k) {
        var rest = reverseByN(curr, k)
        head.next = rest;
        if(rest != null)
             /it is required for prev link otherwise u wont be backtrack list due to broken links
            rest.prev = head;
    }
    return newHead;
}
 
 
var head;
for (var i = 1; i <= 10; i++) {
    head = insertAtEnd(head, i);
}
printDLL(head);
var n = 4;
head = reverseByN(head, n);
printDLL(head);
 
</script>
Output
1 2 3 4 5 6 7 8 9 10 
4 3 2 1 8 7 6 5 10 9 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :